Browse Source

Move email_queue to the core

markjcrane 8 tháng trước cách đây
mục cha
commit
a8f353811c

+ 278 - 0
core/email_queue/app_config.php

@@ -0,0 +1,278 @@
+<?php
+
+	//application details
+		$apps[$x]['name'] = 'Email Queue';
+		$apps[$x]['uuid'] = '5befdf60-a242-445f-91b3-2e9ee3e0ddf7';
+		$apps[$x]['category'] = 'system';
+		$apps[$x]['subcategory'] = 'email';
+		$apps[$x]['version'] = '2.11';
+		$apps[$x]['license'] = 'Member';
+		$apps[$x]['url'] = 'http://www.fusionpbx.com';
+		$apps[$x]['description']['en-us'] = '';
+
+	//default settings
+		$y=0;
+		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "35c40afc-8b08-45f1-a96c-2f8a5352cd2d";
+		$apps[$x]['default_settings'][$y]['default_setting_category'] = "email_queue";
+		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "enabled";
+		$apps[$x]['default_settings'][$y]['default_setting_name'] = "boolean";
+		$apps[$x]['default_settings'][$y]['default_setting_value'] = "true";
+		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true";
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = "Enable or disable the email queue.";
+		$y++;
+		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "237efdc4-ba71-4c8f-8040-28d0e3a3d6bf";
+		$apps[$x]['default_settings'][$y]['default_setting_category'] = "email_queue";
+		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "limit";
+		$apps[$x]['default_settings'][$y]['default_setting_name'] = "numeric";
+		$apps[$x]['default_settings'][$y]['default_setting_value'] = "30";
+		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true";
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = "Limit the records to process at one time.";
+		$y++;
+		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "c4905655-2d67-4eda-9df0-029931c12c6f";
+		$apps[$x]['default_settings'][$y]['default_setting_category'] = "email_queue";
+		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "interval";
+		$apps[$x]['default_settings'][$y]['default_setting_name'] = "numeric";
+		$apps[$x]['default_settings'][$y]['default_setting_value'] = "5";
+		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true";
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = "How often to process the email queue. Default 5 seconds.";
+		$y++;
+		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "d945ed66-39c1-44eb-b596-49c9399d8018";
+		$apps[$x]['default_settings'][$y]['default_setting_category'] = "email_queue";
+		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "retry_limit";
+		$apps[$x]['default_settings'][$y]['default_setting_name'] = "numeric";
+		$apps[$x]['default_settings'][$y]['default_setting_value'] = "5";
+		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true";
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = "Limit the number of attempts before the email is set to failed.";
+		$y++;
+		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "27c6f91a-7362-4028-95d1-bf05539fdf3b";
+		$apps[$x]['default_settings'][$y]['default_setting_category'] = "email_queue";
+		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "save_response";
+		$apps[$x]['default_settings'][$y]['default_setting_name'] = "boolean";
+		$apps[$x]['default_settings'][$y]['default_setting_value'] = "false";
+		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true";
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = "Save the SMTP send response. Use this for debugging SMTP response.";
+		$y++;
+		//$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "a9eb5a16-e018-4a83-975e-eee2ed31f923";
+		//$apps[$x]['default_settings'][$y]['default_setting_category'] = "email_queue";
+		//$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "retry_interval";
+		//$apps[$x]['default_settings'][$y]['default_setting_name'] = "numeric";
+		//$apps[$x]['default_settings'][$y]['default_setting_value'] = "300";
+		//$apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true";
+		//$apps[$x]['default_settings'][$y]['default_setting_description'] = "Time in seconds to wait before trying to email again. Default 300 seconds";
+
+	//permission details
+		$y = 0;
+		$apps[$x]['permissions'][$y]['name'] = 'email_queue_view';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		//$apps[$x]['permissions'][$y]['groups'][] = 'admin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'email_queue_add';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		//$apps[$x]['permissions'][$y]['groups'][] = 'admin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'email_queue_edit';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		//$apps[$x]['permissions'][$y]['groups'][] = 'admin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'email_queue_delete';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		//$apps[$x]['permissions'][$y]['groups'][] = 'admin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'email_queue_all';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'email_queue_attachment_view';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		//$apps[$x]['permissions'][$y]['groups'][] = 'admin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'email_queue_attachment_add';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		//$apps[$x]['permissions'][$y]['groups'][] = 'admin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'email_queue_attachment_edit';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		//$apps[$x]['permissions'][$y]['groups'][] = 'admin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'email_queue_attachment_delete';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		//$apps[$x]['permissions'][$y]['groups'][] = 'admin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'email_queue_attachment_all';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		$y++;
+
+	//email queue
+		$y = 0;
+		$apps[$x]['db'][$y]['table']['name'] = 'v_email_queue';
+		$apps[$x]['db'][$y]['table']['parent'] = '';
+		$z = 0;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_queue_uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'primary';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'domain_uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'foreign';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['table'] = 'v_domains';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['field'] = 'domain_uuid';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'hostname';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'true';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_date';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'false';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_from';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'true';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_to';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'true';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_subject';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'true';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_body';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'true';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_status';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'true';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_retry_count';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'numeric';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'false';
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = '';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_action_before';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'true';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_action_after';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'true';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_transcription';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'true';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name']['text'] = 'email_response';
+		$apps[$x]['db'][$y]['fields'][$z]['name']['deprecated'] = 'email_debug';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		//$apps[$x]['db'][$y]['fields'][$z]['search_by'] = 'true';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = "insert_date";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date';
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "";
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = "insert_user";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)";
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "";
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = "update_date";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date';
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "";
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = "update_user";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)";
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "";
+
+	//attachments
+		$y = 6;
+		$apps[$x]['db'][$y]['table']['name'] = 'v_email_queue_attachments';
+		$apps[$x]['db'][$y]['table']['parent'] = 'v_email_queue';
+		$z = 0;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_queue_attachment_uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'primary';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'domain_uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'foreign';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['table'] = 'v_domains';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['field'] = 'domain_uuid';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_queue_uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'foreign';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['table'] = 'v_email_queue';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['field'] = 'email_queue_uuid';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_attachment_mime_type';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = '';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_attachment_type';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = '';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_attachment_path';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = '';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_attachment_name';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = '';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_attachment_base64';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = '';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'email_attachment_cid';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['search_by'] = '';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = "insert_date";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date';
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "";
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = "insert_user";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)";
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "";
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = "update_date";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'timestamptz';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'date';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'date';
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "";
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = "update_user";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text";
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)";
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "";
+
+?>

+ 948 - 0
core/email_queue/app_languages.php

@@ -0,0 +1,948 @@
+<?php
+
+$text['title-email_queue']['en-us'] = "Email Queue";
+$text['title-email_queue']['en-gb'] = "Email Queue";
+$text['title-email_queue']['ar-eg'] = "قائمة انتظار البريد الإلكتروني";
+$text['title-email_queue']['de-at'] = "Email Warteschlange";
+$text['title-email_queue']['de-ch'] = "Email Warteschlange";
+$text['title-email_queue']['de-de'] = "Email Warteschlange";
+$text['title-email_queue']['el-gr'] = "Ουρά email";
+$text['title-email_queue']['es-cl'] = "Correo electrónico";
+$text['title-email_queue']['es-mx'] = "Correo electrónico";
+$text['title-email_queue']['fr-ca'] = "File d'attente des e-mails";
+$text['title-email_queue']['fr-fr'] = "File d'attente des e-mails";
+$text['title-email_queue']['he-il'] = "דואר אלקטרוני Queue";
+$text['title-email_queue']['it-it'] = "Coda di posta elettronica";
+$text['title-email_queue']['ka-ge'] = "ელფოსტის რიგი";
+$text['title-email_queue']['nl-nl'] = "E-mailwachtrij";
+$text['title-email_queue']['pl-pl'] = "pocztówka";
+$text['title-email_queue']['pt-br'] = "Enquete de Email";
+$text['title-email_queue']['pt-pt'] = "Enquete de Email";
+$text['title-email_queue']['ro-ro'] = "Coada de e-mailuri";
+$text['title-email_queue']['ru-ru'] = "Очередь электронной почты";
+$text['title-email_queue']['sv-se'] = "e-post kö";
+$text['title-email_queue']['uk-ua'] = "Електронна пошта";
+$text['title-email_queue']['tr-tr'] = "E-posta Kuyruğu";
+$text['title-email_queue']['zh-cn'] = "电子邮件队列";
+$text['title-email_queue']['ja-jp'] = "電子メールキュー";
+$text['title-email_queue']['ko-kr'] = "이메일 대기열";
+
+$text['title_description-email_queue']['en-us'] = "Email Queue Description";
+$text['title_description-email_queue']['en-gb'] = "Email Queue Description";
+$text['title_description-email_queue']['ar-eg'] = "وصف قائمة انتظار البريد الإلكتروني";
+$text['title_description-email_queue']['de-at'] = "Beschreibung der E-Mail-Warteschlange";
+$text['title_description-email_queue']['de-ch'] = "Beschreibung der E-Mail-Warteschlange";
+$text['title_description-email_queue']['de-de'] = "Beschreibung der E-Mail-Warteschlange";
+$text['title_description-email_queue']['el-gr'] = "E-posta Kuyruğu Açıklaması";
+$text['title_description-email_queue']['es-cl'] = "Descripción de la cola de correo electrónico";
+$text['title_description-email_queue']['es-mx'] = "Descripción de la cola de correo electrónico";
+$text['title_description-email_queue']['fr-ca'] = "Description de la file d'attente de courrier électronique";
+$text['title_description-email_queue']['fr-fr'] = "Description de la file d'attente de courrier électronique";
+$text['title_description-email_queue']['he-il'] = "תיאור תור דוא ל";
+$text['title_description-email_queue']['it-it'] = "Descrizione della coda di posta elettronica";
+$text['title_description-email_queue']['ka-ge'] = "ელფოსტის რიგის აღწერა";
+$text['title_description-email_queue']['nl-nl'] = "Beschrijving e-mailwachtrij";
+$text['title_description-email_queue']['pl-pl'] = "Opis kolejki e-mail";
+$text['title_description-email_queue']['pt-br'] = "Descrição da fila de e-mail";
+$text['title_description-email_queue']['pt-pt'] = "Descrição da fila de e-mail";
+$text['title_description-email_queue']['ro-ro'] = "Descrierea cozii de e-mail";
+$text['title_description-email_queue']['ru-ru'] = "Описание очереди электронной почты";
+$text['title_description-email_queue']['sv-se'] = "E-postköbeskrivning";
+$text['title_description-email_queue']['uk-ua'] = "Опис черги електронної пошти";
+$text['title_description-email_queue']['tr-tr'] = "Περιγραφή ουράς email";
+$text['title_description-email_queue']['zh-cn'] = "电子邮件队列描述";
+$text['title_description-email_queue']['ja-jp'] = "電子メールキューの説明";
+$text['title_description-email_queue']['ko-kr'] = "이메일 대기열 설명";
+
+$text['label-email_date']['en-us'] = "Date";
+$text['label-email_date']['en-gb'] = "Date";
+$text['label-email_date']['ar-eg'] = "التاريخ";
+$text['label-email_date']['de-at'] = "Datum";
+$text['label-email_date']['de-ch'] = "Datum";
+$text['label-email_date']['de-de'] = "Datum";
+$text['label-email_date']['el-gr'] = "Ημερομηνία";
+$text['label-email_date']['es-cl'] = "Fecha";
+$text['label-email_date']['es-mx'] = "Fecha";
+$text['label-email_date']['fr-ca'] = "date";
+$text['label-email_date']['fr-fr'] = "date";
+$text['label-email_date']['he-il'] = "תַאֲרִיך";
+$text['label-email_date']['it-it'] = "Data";
+$text['label-email_date']['ka-ge'] = "თარიღი";
+$text['label-email_date']['nl-nl'] = "Datum";
+$text['label-email_date']['pl-pl'] = "Data";
+$text['label-email_date']['pt-br'] = "Data";
+$text['label-email_date']['pt-pt'] = "Data";
+$text['label-email_date']['ro-ro'] = "Data";
+$text['label-email_date']['ru-ru'] = "Дата";
+$text['label-email_date']['sv-se'] = "Datum";
+$text['label-email_date']['uk-ua'] = "Дата";
+$text['label-email_date']['tr-tr'] = "Tarih";
+$text['label-email_date']['zh-cn'] = "日期";
+$text['label-email_date']['ja-jp'] = "日にち";
+$text['label-email_date']['ko-kr'] = "날짜";
+
+$text['description-email_date']['en-us'] = "Enter the email date.";
+$text['description-email_date']['en-gb'] = "Enter the email date.";
+$text['description-email_date']['ar-eg'] = "أدخل تاريخ البريد الإلكتروني";
+$text['description-email_date']['de-at'] = "Geben Sie das E-Mail-Datum ein.";
+$text['description-email_date']['de-ch'] = "Geben Sie das E-Mail-Datum ein.";
+$text['description-email_date']['de-de'] = "Geben Sie das E-Mail-Datum ein.";
+$text['description-email_date']['el-gr'] = "Εισαγάγετε την ημερομηνία email.";
+$text['description-email_date']['es-cl'] = "Introduzca la fecha de correo electrónico.";
+$text['description-email_date']['es-mx'] = "Introduzca la fecha de correo electrónico.";
+$text['description-email_date']['fr-ca'] = "Entrez la date de courriel.";
+$text['description-email_date']['fr-fr'] = "Entrez la date de courriel.";
+$text['description-email_date']['he-il'] = "הזן את תאריך הדואר האלקטרוני.";
+$text['description-email_date']['it-it'] = "Inserisci la data dell'email.";
+$text['description-email_date']['ka-ge'] = "შეიყვანეთ ელფოსტის თარიღი.";
+$text['description-email_date']['nl-nl'] = "Voer de e-maildatum in.";
+$text['description-email_date']['pl-pl'] = "Wejście do e-maila.";
+$text['description-email_date']['pt-br'] = "Digite a data de e-mail.";
+$text['description-email_date']['pt-pt'] = "Digite a data de e-mail.";
+$text['description-email_date']['ro-ro'] = "Introduceți data e-mailului.";
+$text['description-email_date']['ru-ru'] = "Введите дату электронной почты.";
+$text['description-email_date']['sv-se'] = "Ange e-postdatumet.";
+$text['description-email_date']['uk-ua'] = "Введіть дату електронної пошти.";
+$text['description-email_date']['tr-tr'] = "E-posta tarihini girin.";
+$text['description-email_date']['zh-cn'] = "输入电子邮件日期。";
+$text['description-email_date']['ja-jp'] = "メールの日付を入力します。";
+$text['description-email_date']['ko-kr'] = "이메일 날짜를 입력합니다.";
+
+$text['label-email_from']['en-us'] = "From";
+$text['label-email_from']['en-gb'] = "From";
+$text['label-email_from']['ar-eg'] = "من";
+$text['label-email_from']['de-at'] = "Von";
+$text['label-email_from']['de-ch'] = "Von";
+$text['label-email_from']['de-de'] = "Von";
+$text['label-email_from']['el-gr'] = "Από";
+$text['label-email_from']['es-cl'] = "Desde";
+$text['label-email_from']['es-mx'] = "Desde";
+$text['label-email_from']['fr-ca'] = "De";
+$text['label-email_from']['fr-fr'] = "De";
+$text['label-email_from']['he-il'] = "מתוך";
+$text['label-email_from']['it-it'] = "Da";
+$text['label-email_from']['ka-ge'] = "ვისგან";
+$text['label-email_from']['nl-nl'] = "Van";
+$text['label-email_from']['pl-pl'] = "od";
+$text['label-email_from']['pt-br'] = "A partir de";
+$text['label-email_from']['pt-pt'] = "A partir de";
+$text['label-email_from']['ro-ro'] = "Din";
+$text['label-email_from']['ru-ru'] = "Из";
+$text['label-email_from']['sv-se'] = "Från";
+$text['label-email_from']['uk-ua'] = "Від";
+$text['label-email_from']['tr-tr'] = "İtibaren";
+$text['label-email_from']['zh-cn'] = "从";
+$text['label-email_from']['ja-jp'] = "から";
+$text['label-email_from']['ko-kr'] = "에서";
+
+$text['description-email_from']['en-us'] = "Enter the email from.";
+$text['description-email_from']['en-gb'] = "Enter the email from.";
+$text['description-email_from']['ar-eg'] = "أدخل الرسالة من";
+$text['description-email_from']['de-at'] = "Geben Sie die E-Mail ein.";
+$text['description-email_from']['de-ch'] = "Geben Sie die E-Mail ein.";
+$text['description-email_from']['de-de'] = "Geben Sie die E-Mail ein.";
+$text['description-email_from']['el-gr'] = "Εισαγάγετε το email από.";
+$text['description-email_from']['es-cl'] = "Introduzca el correo de.";
+$text['description-email_from']['es-mx'] = "Introduzca el correo de.";
+$text['description-email_from']['fr-ca'] = "Entrez le courriel de.";
+$text['description-email_from']['fr-fr'] = "Entrez le courriel de.";
+$text['description-email_from']['he-il'] = "הזן את הדואר האלקטרוני.";
+$text['description-email_from']['it-it'] = "Inserisci l'email da.";
+$text['description-email_from']['ka-ge'] = "შეიყვანეთ, ვისგანაა ელფოსტა.";
+$text['description-email_from']['nl-nl'] = "Breng de e-mail binnen.";
+$text['description-email_from']['pl-pl'] = "Wstęp do e-maila.";
+$text['description-email_from']['pt-br'] = "Entre no e-mail.";
+$text['description-email_from']['pt-pt'] = "Entre no e-mail.";
+$text['description-email_from']['ro-ro'] = "Introdu e-mailul de la.";
+$text['description-email_from']['ru-ru'] = "Введите письмо.";
+$text['description-email_from']['sv-se'] = "Ange e-post från.";
+$text['description-email_from']['uk-ua'] = "Введіть електронну пошту.";
+$text['description-email_from']['tr-tr'] = "Gönderen e-postayı girin.";
+$text['description-email_from']['zh-cn'] = "输入发件人的电子邮件。";
+$text['description-email_from']['ja-jp'] = "からのメールを入力します。";
+$text['description-email_from']['ko-kr'] = "보낸 이메일을 입력합니다.";
+
+$text['label-email_to']['en-us'] = "To";
+$text['label-email_to']['en-gb'] = "To";
+$text['label-email_to']['ar-eg'] = "إلى";
+$text['label-email_to']['de-at'] = "Zu";
+$text['label-email_to']['de-ch'] = "Zu";
+$text['label-email_to']['de-de'] = "Zu";
+$text['label-email_to']['el-gr'] = "İle";
+$text['label-email_to']['es-cl'] = "A";
+$text['label-email_to']['es-mx'] = "A";
+$text['label-email_to']['fr-ca'] = "to";
+$text['label-email_to']['fr-fr'] = "to";
+$text['label-email_to']['he-il'] = "כדי";
+$text['label-email_to']['it-it'] = "A";
+$text['label-email_to']['ka-ge'] = "ვის";
+$text['label-email_to']['nl-nl'] = "Naar";
+$text['label-email_to']['pl-pl'] = "Aby to zrobić";
+$text['label-email_to']['pt-br'] = "Para";
+$text['label-email_to']['pt-pt'] = "Para";
+$text['label-email_to']['ro-ro'] = "La";
+$text['label-email_to']['ru-ru'] = "в";
+$text['label-email_to']['sv-se'] = "för att";
+$text['label-email_to']['uk-ua'] = "до";
+$text['label-email_to']['tr-tr'] = "Προς την";
+$text['label-email_to']['zh-cn'] = "到";
+$text['label-email_to']['ja-jp'] = "に";
+$text['label-email_to']['ko-kr'] = "에게";
+
+$text['description-email_to']['en-us'] = "Enter the email to.";
+$text['description-email_to']['en-gb'] = "Enter the email to.";
+$text['description-email_to']['ar-eg'] = "أدخل البريد الإلكتروني إلى.";
+$text['description-email_to']['de-at'] = "Geben Sie die E-Mail an.";
+$text['description-email_to']['de-ch'] = "Geben Sie die E-Mail an.";
+$text['description-email_to']['de-de'] = "Geben Sie die E-Mail an.";
+$text['description-email_to']['el-gr'] = "Εισαγάγετε το email στο.";
+$text['description-email_to']['es-cl'] = "Introduzca el correo electrónico a.";
+$text['description-email_to']['es-mx'] = "Introduzca el correo electrónico a.";
+$text['description-email_to']['fr-ca'] = "Entrez le courriel à.";
+$text['description-email_to']['fr-fr'] = "Entrez le courriel à.";
+$text['description-email_to']['he-il'] = "הזן את הדואר האלקטרוני.";
+$text['description-email_to']['it-it'] = "Inserisci l'email a.";
+$text['description-email_to']['ka-ge'] = "შეიყვანეთ, ვის უგზავნით ელფოსტას.";
+$text['description-email_to']['nl-nl'] = "Breng de e-mail binnen.";
+$text['description-email_to']['pl-pl'] = "Wstęp do e-maila.";
+$text['description-email_to']['pt-br'] = "Insira o e-mail para.";
+$text['description-email_to']['pt-pt'] = "Insira o e-mail para.";
+$text['description-email_to']['ro-ro'] = "Introdu e-mailul către.";
+$text['description-email_to']['ru-ru'] = "Введите письмо.";
+$text['description-email_to']['sv-se'] = "Ange e-post till.";
+$text['description-email_to']['uk-ua'] = "Введіть адресу електронної пошти.";
+$text['description-email_to']['tr-tr'] = "E-postayı girin.";
+$text['description-email_to']['zh-cn'] = "输入电子邮件至。";
+$text['description-email_to']['ja-jp'] = "宛先のメールアドレスを入力してください。";
+$text['description-email_to']['ko-kr'] = "이메일 주소를 입력하세요.";
+
+$text['label-email_cc']['en-us'] = "CC";
+$text['label-email_cc']['en-gb'] = "CC";
+$text['label-email_cc']['ar-eg'] = "CC";
+$text['label-email_cc']['de-at'] = "CC";
+$text['label-email_cc']['de-ch'] = "CC";
+$text['label-email_cc']['de-de'] = "CC";
+$text['label-email_cc']['el-gr'] = "CC";
+$text['label-email_cc']['es-cl'] = "CC";
+$text['label-email_cc']['es-mx'] = "CC";
+$text['label-email_cc']['fr-ca'] = "CC";
+$text['label-email_cc']['fr-fr'] = "CC";
+$text['label-email_cc']['he-il'] = "CC";
+$text['label-email_cc']['it-it'] = "CC";
+$text['label-email_cc']['ka-ge'] = "CC";
+$text['label-email_cc']['nl-nl'] = "CC";
+$text['label-email_cc']['pl-pl'] = "CC";
+$text['label-email_cc']['pt-br'] = "CC";
+$text['label-email_cc']['pt-pt'] = "CC";
+$text['label-email_cc']['ro-ro'] = "CC";
+$text['label-email_cc']['ru-ru'] = "CC";
+$text['label-email_cc']['sv-se'] = "CC";
+$text['label-email_cc']['uk-ua'] = "CC";
+$text['label-email_cc']['tr-tr'] = "CC";
+$text['label-email_cc']['zh-cn'] = "CC";
+$text['label-email_cc']['ja-jp'] = "CC";
+$text['label-email_cc']['ko-kr'] = "CC";
+
+$text['description-email_cc']['en-us'] = "Enter the email cc.";
+$text['description-email_cc']['en-gb'] = "Enter the email cc.";
+$text['description-email_cc']['ar-eg'] = "أدخلي البريد الإلكتروني";
+$text['description-email_cc']['de-at'] = "Geben Sie die E-Mail cc.";
+$text['description-email_cc']['de-ch'] = "Geben Sie die E-Mail cc.";
+$text['description-email_cc']['de-de'] = "Geben Sie die E-Mail cc.";
+$text['description-email_cc']['el-gr'] = "Εισαγάγετε το email cc.";
+$text['description-email_cc']['es-cl'] = "Introduzca el cc de correo electrónico.";
+$text['description-email_cc']['es-mx'] = "Introduzca el cc de correo electrónico.";
+$text['description-email_cc']['fr-ca'] = "Entrez le courriel cc.";
+$text['description-email_cc']['fr-fr'] = "Entrez le courriel cc.";
+$text['description-email_cc']['he-il'] = "היכנס לדואר האלקטרוני.";
+$text['description-email_cc']['it-it'] = "Inserisci l'email cc.";
+$text['description-email_cc']['ka-ge'] = "შეიყვანეთ ელფოსტის CC.";
+$text['description-email_cc']['nl-nl'] = "Voer de e-mail cc in.";
+$text['description-email_cc']['pl-pl'] = "Wejście do e-maila.";
+$text['description-email_cc']['pt-br'] = "Digite o e-mail cc.";
+$text['description-email_cc']['pt-pt'] = "Digite o e-mail cc.";
+$text['description-email_cc']['ro-ro'] = "Introdu e-mailul cc.";
+$text['description-email_cc']['ru-ru'] = "Введите адрес электронной почты.";
+$text['description-email_cc']['sv-se'] = "Ange e-post cc.";
+$text['description-email_cc']['uk-ua'] = "Введіть електронну пошту cc.";
+$text['description-email_cc']['tr-tr'] = "E-posta cc'sini girin.";
+$text['description-email_cc']['zh-cn'] = "输入电子邮件抄送。";
+$text['description-email_cc']['ja-jp'] = "メールアドレス「CC」を入力します。";
+$text['description-email_cc']['ko-kr'] = "이메일 참조를 입력하십시오.";
+
+$text['label-email_bcc']['en-us'] = "BCC";
+$text['label-email_bcc']['en-gb'] = "BCC";
+$text['label-email_bcc']['ar-eg'] = "BCC";
+$text['label-email_bcc']['de-at'] = "BCC";
+$text['label-email_bcc']['de-ch'] = "BCC";
+$text['label-email_bcc']['de-de'] = "BCC";
+$text['label-email_bcc']['el-gr'] = "BCC";
+$text['label-email_bcc']['es-cl'] = "BCC";
+$text['label-email_bcc']['es-mx'] = "BCC";
+$text['label-email_bcc']['fr-ca'] = "BCC";
+$text['label-email_bcc']['fr-fr'] = "BCC";
+$text['label-email_bcc']['he-il'] = "BCC";
+$text['label-email_bcc']['it-it'] = "BCC";
+$text['label-email_bcc']['ka-ge'] = "BCC";
+$text['label-email_bcc']['nl-nl'] = "BCC";
+$text['label-email_bcc']['pl-pl'] = "BCC";
+$text['label-email_bcc']['pt-br'] = "BCC";
+$text['label-email_bcc']['pt-pt'] = "BCC";
+$text['label-email_bcc']['ro-ro'] = "BCC";
+$text['label-email_bcc']['ru-ru'] = "BCC";
+$text['label-email_bcc']['sv-se'] = "BCC";
+$text['label-email_bcc']['uk-ua'] = "BCC";
+$text['label-email_bcc']['tr-tr'] = "BCC";
+$text['label-email_bcc']['zh-cn'] = "BCC";
+$text['label-email_bcc']['ja-jp'] = "BCC";
+$text['label-email_bcc']['ko-kr'] = "BCC";
+
+$text['description-email_bcc']['en-us'] = "Enter the email bcc.";
+$text['description-email_bcc']['en-gb'] = "Enter the email bcc.";
+$text['description-email_bcc']['ar-eg'] = "أدخلي كاميرا البريد الإلكتروني";
+$text['description-email_bcc']['de-at'] = "Geben Sie die E-Mail bcc ein.";
+$text['description-email_bcc']['de-ch'] = "Geben Sie die E-Mail bcc ein.";
+$text['description-email_bcc']['de-de'] = "Geben Sie die E-Mail bcc ein.";
+$text['description-email_bcc']['el-gr'] = "Εισαγάγετε το email bcc.";
+$text['description-email_bcc']['es-cl'] = "Introduzca el correo electrónico bcc.";
+$text['description-email_bcc']['es-mx'] = "Introduzca el correo electrónico bcc.";
+$text['description-email_bcc']['fr-ca'] = "Entrez l'e-mail bcc.";
+$text['description-email_bcc']['fr-fr'] = "Entrez l'e-mail bcc.";
+$text['description-email_bcc']['he-il'] = "הזן את הדואר האלקטרוני.";
+$text['description-email_bcc']['it-it'] = "Inserisci l'email bcc.";
+$text['description-email_bcc']['ka-ge'] = "შეიყვანეთ ელფოსტის BCC.";
+$text['description-email_bcc']['nl-nl'] = "Voer de e-mail bcc in.";
+$text['description-email_bcc']['pl-pl'] = "Wejście do e-maila bcc.";
+$text['description-email_bcc']['pt-br'] = "Digite o e-mail bcc.";
+$text['description-email_bcc']['pt-pt'] = "Digite o e-mail bcc.";
+$text['description-email_bcc']['ro-ro'] = "Introdu e-mailul bcc.";
+$text['description-email_bcc']['ru-ru'] = "Введите e-mail bcc.";
+$text['description-email_bcc']['sv-se'] = "Ange e-post bcc.";
+$text['description-email_bcc']['uk-ua'] = "Введіть електронну пошту bcc.";
+$text['description-email_bcc']['tr-tr'] = "E-posta bcc'yi girin.";
+$text['description-email_bcc']['zh-cn'] = "输入电子邮件密件抄送。";
+$text['description-email_bcc']['ja-jp'] = "メールアドレスのBCCを入力してください。";
+$text['description-email_bcc']['ko-kr'] = "이메일 숨은 참조를 입력하십시오.";
+
+$text['label-email_subject']['en-us'] = "Subject";
+$text['label-email_subject']['en-gb'] = "Subject";
+$text['label-email_subject']['ar-eg'] = "الموضوع";
+$text['label-email_subject']['de-at'] = "Gegenstand";
+$text['label-email_subject']['de-ch'] = "Gegenstand";
+$text['label-email_subject']['de-de'] = "Gegenstand";
+$text['label-email_subject']['el-gr'] = "Θέμα";
+$text['label-email_subject']['es-cl'] = "Asunto";
+$text['label-email_subject']['es-mx'] = "Asunto";
+$text['label-email_subject']['fr-ca'] = "sujet";
+$text['label-email_subject']['fr-fr'] = "sujet";
+$text['label-email_subject']['he-il'] = "נושא";
+$text['label-email_subject']['it-it'] = "Oggetto";
+$text['label-email_subject']['ka-ge'] = "თემა";
+$text['label-email_subject']['nl-nl'] = "Vertaling:";
+$text['label-email_subject']['pl-pl'] = "przedmiot";
+$text['label-email_subject']['pt-br'] = "Assunto";
+$text['label-email_subject']['pt-pt'] = "Assunto";
+$text['label-email_subject']['ro-ro'] = "Subiect";
+$text['label-email_subject']['ru-ru'] = "Тема";
+$text['label-email_subject']['sv-se'] = "Subjekt";
+$text['label-email_subject']['uk-ua'] = "Головна";
+$text['label-email_subject']['tr-tr'] = "Ders";
+$text['label-email_subject']['zh-cn'] = "主題";
+$text['label-email_subject']['ja-jp'] = "コンテンツ";
+$text['label-email_subject']['ko-kr'] = "주제";
+
+$text['description-email_subject']['en-us'] = "Enter the email subject.";
+$text['description-email_subject']['en-gb'] = "Enter the email subject.";
+$text['description-email_subject']['ar-eg'] = "أدخل موضوع البريد الإلكتروني";
+$text['description-email_subject']['de-at'] = "Geben Sie das E-Mail-Thema ein.";
+$text['description-email_subject']['de-ch'] = "Geben Sie das E-Mail-Thema ein.";
+$text['description-email_subject']['de-de'] = "Geben Sie das E-Mail-Thema ein.";
+$text['description-email_subject']['el-gr'] = "Εισαγάγετε το θέμα του email.";
+$text['description-email_subject']['es-cl'] = "Introduzca el tema de correo electrónico.";
+$text['description-email_subject']['es-mx'] = "Introduzca el tema de correo electrónico.";
+$text['description-email_subject']['fr-ca'] = "Entrez le sujet de courriel.";
+$text['description-email_subject']['fr-fr'] = "Entrez le sujet de courriel.";
+$text['description-email_subject']['he-il'] = "היכנס לנושא הדואר האלקטרוני.";
+$text['description-email_subject']['it-it'] = "Inserisci l'oggetto e-mail.";
+$text['description-email_subject']['ka-ge'] = "შეიყვანეთ ელფოსტის თემა.";
+$text['description-email_subject']['nl-nl'] = "Voer het e-mail onderwerp in.";
+$text['description-email_subject']['pl-pl'] = "Wejście do wiadomości e-mail.";
+$text['description-email_subject']['pt-br'] = "Digite o assunto do email.";
+$text['description-email_subject']['pt-pt'] = "Digite o assunto do email.";
+$text['description-email_subject']['ro-ro'] = "Introduceți subiectul e-mailului.";
+$text['description-email_subject']['ru-ru'] = "Введите тему электронной почты.";
+$text['description-email_subject']['sv-se'] = "Ange e-postämnet.";
+$text['description-email_subject']['uk-ua'] = "Введіть тему електронної пошти.";
+$text['description-email_subject']['tr-tr'] = "E-posta konusunu girin.";
+$text['description-email_subject']['zh-cn'] = "输入电子邮件主题。";
+$text['description-email_subject']['ja-jp'] = "メールの件名を入力します。";
+$text['description-email_subject']['ko-kr'] = "이메일 제목을 입력하세요.";
+
+$text['label-email_body']['en-us'] = "Body";
+$text['label-email_body']['en-gb'] = "Body";
+$text['label-email_body']['ar-eg'] = "الهيئة";
+$text['label-email_body']['de-at'] = "Körper";
+$text['label-email_body']['de-ch'] = "Körper";
+$text['label-email_body']['de-de'] = "Körper";
+$text['label-email_body']['el-gr'] = "Σώμα";
+$text['label-email_body']['es-cl'] = "Cuerpo";
+$text['label-email_body']['es-mx'] = "Cuerpo";
+$text['label-email_body']['fr-ca'] = "Corps";
+$text['label-email_body']['fr-fr'] = "Corps";
+$text['label-email_body']['he-il'] = "גוף הגוף";
+$text['label-email_body']['it-it'] = "Corpo";
+$text['label-email_body']['ka-ge'] = "სხეული";
+$text['label-email_body']['nl-nl'] = "lichaam.";
+$text['label-email_body']['pl-pl'] = "ciało";
+$text['label-email_body']['pt-br'] = "Corpo";
+$text['label-email_body']['pt-pt'] = "Corpo";
+$text['label-email_body']['ro-ro'] = "Corp";
+$text['label-email_body']['ru-ru'] = "Тело";
+$text['label-email_body']['sv-se'] = "Kropp";
+$text['label-email_body']['uk-ua'] = "Тіло";
+$text['label-email_body']['tr-tr'] = "Vücut";
+$text['label-email_body']['zh-cn'] = "身体";
+$text['label-email_body']['ja-jp'] = "体";
+$text['label-email_body']['ko-kr'] = "몸";
+
+$text['description-email_body']['en-us'] = "Enter the email body.";
+$text['description-email_body']['en-gb'] = "Enter the email body.";
+$text['description-email_body']['ar-eg'] = "أدخلي الجثة";
+$text['description-email_body']['de-at'] = "Geben Sie die E-Mail-Körper ein.";
+$text['description-email_body']['de-ch'] = "Geben Sie die E-Mail-Körper ein.";
+$text['description-email_body']['de-de'] = "Geben Sie die E-Mail-Körper ein.";
+$text['description-email_body']['el-gr'] = "Εισαγάγετε το σώμα του email.";
+$text['description-email_body']['es-cl'] = "Introduzca el cuerpo de correo electrónico.";
+$text['description-email_body']['es-mx'] = "Introduzca el cuerpo de correo electrónico.";
+$text['description-email_body']['fr-ca'] = "Entrez le corps de courriel.";
+$text['description-email_body']['fr-fr'] = "Entrez le corps de courriel.";
+$text['description-email_body']['he-il'] = "היכנסו לגוף הדואר האלקטרוני";
+$text['description-email_body']['it-it'] = "Inserisci il corpo e-mail.";
+$text['description-email_body']['ka-ge'] = "შეიყვანეთ ელფოსტის შემცველობა.";
+$text['description-email_body']['nl-nl'] = "In het e-mail lichaam.";
+$text['description-email_body']['pl-pl'] = "Wejście do organu pocztowego.";
+$text['description-email_body']['pt-br'] = "Digite o corpo de e-mail.";
+$text['description-email_body']['pt-pt'] = "Digite o corpo de e-mail.";
+$text['description-email_body']['ro-ro'] = "Introduceți corpul e-mailului.";
+$text['description-email_body']['ru-ru'] = "Введите тело электронной почты.";
+$text['description-email_body']['sv-se'] = "Ange e-postkroppen.";
+$text['description-email_body']['uk-ua'] = "Введіть тіло електронної пошти.";
+$text['description-email_body']['tr-tr'] = "E-posta gövdesini girin.";
+$text['description-email_body']['zh-cn'] = "输入电子邮件正文。";
+$text['description-email_body']['ja-jp'] = "メール本文を入力します。";
+$text['description-email_body']['ko-kr'] = "이메일 본문을 입력합니다.";
+
+$text['label-email_status']['en-us'] = "Status";
+$text['label-email_status']['en-gb'] = "Status";
+$text['label-email_status']['ar-eg'] = "الحالة";
+$text['label-email_status']['de-at'] = "Status";
+$text['label-email_status']['de-ch'] = "Status";
+$text['label-email_status']['de-de'] = "Status";
+$text['label-email_status']['el-gr'] = "Κατάσταση";
+$text['label-email_status']['es-cl'] = "Situación";
+$text['label-email_status']['es-mx'] = "Situación";
+$text['label-email_status']['fr-ca'] = "État";
+$text['label-email_status']['fr-fr'] = "État";
+$text['label-email_status']['he-il'] = "סטטוס";
+$text['label-email_status']['it-it'] = "Stato";
+$text['label-email_status']['ka-ge'] = "სტატუსი";
+$text['label-email_status']['nl-nl'] = "status";
+$text['label-email_status']['pl-pl'] = "status";
+$text['label-email_status']['pt-br'] = "Estado";
+$text['label-email_status']['pt-pt'] = "Estado";
+$text['label-email_status']['ro-ro'] = "stare";
+$text['label-email_status']['ru-ru'] = "Статус";
+$text['label-email_status']['sv-se'] = "status";
+$text['label-email_status']['uk-ua'] = "Статус на сервери";
+$text['label-email_status']['tr-tr'] = "Durum";
+$text['label-email_status']['zh-cn'] = "地位";
+$text['label-email_status']['ja-jp'] = "スターテス";
+$text['label-email_status']['ko-kr'] = "상태";
+
+$text['description-email_status']['en-us'] = "Enter the email status.";
+$text['description-email_status']['en-gb'] = "Enter the email status.";
+$text['description-email_status']['ar-eg'] = "أدخلي مركز البريد الإلكتروني";
+$text['description-email_status']['de-at'] = "Geben Sie den E-Mail-Status ein.";
+$text['description-email_status']['de-ch'] = "Geben Sie den E-Mail-Status ein.";
+$text['description-email_status']['de-de'] = "Geben Sie den E-Mail-Status ein.";
+$text['description-email_status']['el-gr'] = "Εισαγάγετε την κατάσταση του email.";
+$text['description-email_status']['es-cl'] = "Introduzca el estado de correo electrónico.";
+$text['description-email_status']['es-mx'] = "Introduzca el estado de correo electrónico.";
+$text['description-email_status']['fr-ca'] = "Entrez le statut de courriel.";
+$text['description-email_status']['fr-fr'] = "Entrez le statut de courriel.";
+$text['description-email_status']['he-il'] = "הזן את מצב הדואר האלקטרוני.";
+$text['description-email_status']['it-it'] = "Inserisci lo stato dell'email.";
+$text['description-email_status']['ka-ge'] = "შეიყვანეთ ელფოსტის სტატუსი.";
+$text['description-email_status']['nl-nl'] = "Voer de e-mail status in.";
+$text['description-email_status']['pl-pl'] = "Wejście do statusu poczty.";
+$text['description-email_status']['pt-br'] = "Digite o status do email.";
+$text['description-email_status']['pt-pt'] = "Digite o status do email.";
+$text['description-email_status']['ro-ro'] = "Introduceți starea e-mailului.";
+$text['description-email_status']['ru-ru'] = "Введите статус электронной почты.";
+$text['description-email_status']['sv-se'] = "Ange e-poststatus.";
+$text['description-email_status']['uk-ua'] = "Введіть статус електронної пошти.";
+$text['description-email_status']['tr-tr'] = "E-posta durumunu girin.";
+$text['description-email_status']['zh-cn'] = "输入电子邮件状态。";
+$text['description-email_status']['ja-jp'] = "メールのステータスを入力します。";
+$text['description-email_status']['ko-kr'] = "이메일 상태를 입력합니다.";
+
+$text['label-email_action_before']['en-us'] = "Before Email";
+$text['label-email_action_before']['en-gb'] = "Before Email";
+$text['label-email_action_before']['ar-eg'] = "قبل البريد الإلكتروني";
+$text['label-email_action_before']['de-at'] = "Vor E-Mail";
+$text['label-email_action_before']['de-ch'] = "Vor E-Mail";
+$text['label-email_action_before']['de-de'] = "Vor E-Mail";
+$text['label-email_action_before']['el-gr'] = "Πριν από το email";
+$text['label-email_action_before']['es-cl'] = "Antes del email";
+$text['label-email_action_before']['es-mx'] = "Antes del email";
+$text['label-email_action_before']['fr-ca'] = "avant courriel";
+$text['label-email_action_before']['fr-fr'] = "avant courriel";
+$text['label-email_action_before']['he-il'] = "לפני דואר אלקטרוני";
+$text['label-email_action_before']['it-it'] = "Prima dell'email";
+$text['label-email_action_before']['ka-ge'] = "ელფოსტამდე";
+$text['label-email_action_before']['nl-nl'] = "Voor e-mail";
+$text['label-email_action_before']['pl-pl'] = "Przed Emailem";
+$text['label-email_action_before']['pt-br'] = "Antes de e-mail";
+$text['label-email_action_before']['pt-pt'] = "Antes de e-mail";
+$text['label-email_action_before']['ro-ro'] = "Înainte de e-mail";
+$text['label-email_action_before']['ru-ru'] = "До Email";
+$text['label-email_action_before']['sv-se'] = "Innan e-post";
+$text['label-email_action_before']['uk-ua'] = "До електронної пошти";
+$text['label-email_action_before']['tr-tr'] = "E-postadan Önce";
+$text['label-email_action_before']['zh-cn'] = "电子邮件之前";
+$text['label-email_action_before']['ja-jp'] = "メールの前に";
+$text['label-email_action_before']['ko-kr'] = "이메일 전";
+
+$text['description-email_action_before']['en-us'] = "Enter the action before sending the email.";
+$text['description-email_action_before']['en-gb'] = "Enter the action before sending the email.";
+$text['description-email_action_before']['ar-eg'] = "أدخل العمل قبل إرسال البريد الإلكتروني";
+$text['description-email_action_before']['de-at'] = "Geben Sie die Aktion ein, bevor Sie die E-Mail senden.";
+$text['description-email_action_before']['de-ch'] = "Geben Sie die Aktion ein, bevor Sie die E-Mail senden.";
+$text['description-email_action_before']['de-de'] = "Geben Sie die Aktion ein, bevor Sie die E-Mail senden.";
+$text['description-email_action_before']['el-gr'] = "Εισαγάγετε την ενέργεια πριν στείλετε το email.";
+$text['description-email_action_before']['es-cl'] = "Introduzca la acción antes de enviar el correo electrónico.";
+$text['description-email_action_before']['es-mx'] = "Introduzca la acción antes de enviar el correo electrónico.";
+$text['description-email_action_before']['fr-ca'] = "Entrez l'action avant d'envoyer le courriel.";
+$text['description-email_action_before']['fr-fr'] = "Entrez l'action avant d'envoyer le courriel.";
+$text['description-email_action_before']['he-il'] = "היכנס לפעולה לפני שליחת הדואר האלקטרוני.";
+$text['description-email_action_before']['it-it'] = "Inserisci l'azione prima di inviare l'e-mail.";
+$text['description-email_action_before']['ka-ge'] = "შეიყვანეთ ელფოსტის გაგზავნამდე შესასრულებელი ქმედება.";
+$text['description-email_action_before']['nl-nl'] = "Voer de actie in voor de e-mail.";
+$text['description-email_action_before']['pl-pl'] = "Przed wysłaniem e-maila.";
+$text['description-email_action_before']['pt-br'] = "Insira a ação antes de enviar o e-mail.";
+$text['description-email_action_before']['pt-pt'] = "Insira a ação antes de enviar o e-mail.";
+$text['description-email_action_before']['ro-ro'] = "Introduceți acțiunea înainte de a trimite e-mailul.";
+$text['description-email_action_before']['ru-ru'] = "Введите действие перед отправкой электронной почты.";
+$text['description-email_action_before']['sv-se'] = "Ange åtgärden innan du skickar e-post.";
+$text['description-email_action_before']['uk-ua'] = "Введіть дію перед відправкою електронної пошти.";
+$text['description-email_action_before']['tr-tr'] = "E-postayı göndermeden önce eylemi girin.";
+$text['description-email_action_before']['zh-cn'] = "在发送电子邮件之前输入操作。";
+$text['description-email_action_before']['ja-jp'] = "メールを送信する前にアクションを入力します。";
+$text['description-email_action_before']['ko-kr'] = "이메일을 보내기 전에 조치를 입력하십시오.";
+
+$text['label-email_action_after']['en-us'] = "After Email";
+$text['label-email_action_after']['en-gb'] = "After Email";
+$text['label-email_action_after']['ar-eg'] = "بعد البريد الإلكتروني";
+$text['label-email_action_after']['de-at'] = "Nach E-Mail";
+$text['label-email_action_after']['de-ch'] = "Nach E-Mail";
+$text['label-email_action_after']['de-de'] = "Nach E-Mail";
+$text['label-email_action_after']['el-gr'] = "Μετά το email";
+$text['label-email_action_after']['es-cl'] = "Después de correo electrónico";
+$text['label-email_action_after']['es-mx'] = "Después de correo electrónico";
+$text['label-email_action_after']['fr-ca'] = "après email";
+$text['label-email_action_after']['fr-fr'] = "après email";
+$text['label-email_action_after']['he-il'] = "לאחר דואר אלקטרוני";
+$text['label-email_action_after']['it-it'] = "Dopo email";
+$text['label-email_action_after']['ka-ge'] = "ელფოსტის შემდეგ";
+$text['label-email_action_after']['nl-nl'] = "Na e-mail";
+$text['label-email_action_after']['pl-pl'] = "Po Emailu";
+$text['label-email_action_after']['pt-br'] = "Depois do e-mail";
+$text['label-email_action_after']['pt-pt'] = "Depois do e-mail";
+$text['label-email_action_after']['ro-ro'] = "După e-mail";
+$text['label-email_action_after']['ru-ru'] = "После Email";
+$text['label-email_action_after']['sv-se'] = "Efter e-post";
+$text['label-email_action_after']['uk-ua'] = "Після електронної пошти";
+$text['label-email_action_after']['tr-tr'] = "E-postadan sonra";
+$text['label-email_action_after']['zh-cn'] = "电子邮件后";
+$text['label-email_action_after']['ja-jp'] = "メール送信後";
+$text['label-email_action_after']['ko-kr'] = "이메일 후";
+
+$text['description-email_action_after']['en-us'] = "Enter the action after sending the email.";
+$text['description-email_action_after']['en-gb'] = "Enter the action after sending the email.";
+$text['description-email_action_after']['ar-eg'] = "أدخل العمل بعد إرسال البريد الإلكتروني";
+$text['description-email_action_after']['de-at'] = "Geben Sie die Aktion nach dem Senden der E-Mail ein.";
+$text['description-email_action_after']['de-ch'] = "Geben Sie die Aktion nach dem Senden der E-Mail ein.";
+$text['description-email_action_after']['de-de'] = "Geben Sie die Aktion nach dem Senden der E-Mail ein.";
+$text['description-email_action_after']['el-gr'] = "Εισαγάγετε την ενέργεια μετά την αποστολή του email.";
+$text['description-email_action_after']['es-cl'] = "Introduzca la acción después de enviar el correo electrónico.";
+$text['description-email_action_after']['es-mx'] = "Introduzca la acción después de enviar el correo electrónico.";
+$text['description-email_action_after']['fr-ca'] = "Entrez l'action après avoir envoyé le courriel.";
+$text['description-email_action_after']['fr-fr'] = "Entrez l'action après avoir envoyé le courriel.";
+$text['description-email_action_after']['he-il'] = "הזן את הפעולה לאחר שליחת הדואר האלקטרוני.";
+$text['description-email_action_after']['it-it'] = "Inserisci l'azione dopo l'invio dell'e-mail.";
+$text['description-email_action_after']['ka-ge'] = "შეიყვანეთ ელფოსტის გაგზავნის შემდეგ შესასრულებელი ქმედება.";
+$text['description-email_action_after']['nl-nl'] = "Voer de actie in nadat je de e-mail stuurde.";
+$text['description-email_action_after']['pl-pl'] = "Po wysłaniu e-maila.";
+$text['description-email_action_after']['pt-br'] = "Insira a ação depois de enviar o e-mail.";
+$text['description-email_action_after']['pt-pt'] = "Insira a ação depois de enviar o e-mail.";
+$text['description-email_action_after']['ro-ro'] = "Introduceți acțiunea după trimiterea e-mailului.";
+$text['description-email_action_after']['ru-ru'] = "Введите действие после отправки электронной почты.";
+$text['description-email_action_after']['sv-se'] = "Ange åtgärden efter att ha skickat e-postmeddelandet.";
+$text['description-email_action_after']['uk-ua'] = "Введіть дію після відправлення електронної пошти.";
+$text['description-email_action_after']['tr-tr'] = "E-postayı gönderdikten sonra eylemi girin.";
+$text['description-email_action_after']['zh-cn'] = "输入发送电子邮件后的操作。";
+$text['description-email_action_after']['ja-jp'] = "メール送信後のアクションを入力します。";
+$text['description-email_action_after']['ko-kr'] = "이메일을 보낸 후 작업을 입력합니다.";
+
+$text['label-email_response']['en-us'] = "Response";
+$text['label-email_response']['en-gb'] = "Response";
+$text['label-email_response']['ar-eg'] = "الرد";
+$text['label-email_response']['de-at'] = "Antwort";
+$text['label-email_response']['de-ch'] = "Antwort";
+$text['label-email_response']['de-de'] = "Antwort";
+$text['label-email_response']['el-gr'] = "Απάντηση";
+$text['label-email_response']['es-cl'] = "Respuesta";
+$text['label-email_response']['es-mx'] = "Respuesta";
+$text['label-email_response']['fr-ca'] = "Réponse";
+$text['label-email_response']['fr-fr'] = "Réponse";
+$text['label-email_response']['he-il'] = "תגובה";
+$text['label-email_response']['it-it'] = "Risposta";
+$text['label-email_response']['ka-ge'] = "პასუხი";
+$text['label-email_response']['nl-nl'] = "Respons.";
+$text['label-email_response']['pl-pl'] = "odpowiedź";
+$text['label-email_response']['pt-br'] = "Resposta";
+$text['label-email_response']['pt-pt'] = "Resposta";
+$text['label-email_response']['ro-ro'] = "Raspuns";
+$text['label-email_response']['ru-ru'] = "Ответ";
+$text['label-email_response']['sv-se'] = "Svar";
+$text['label-email_response']['uk-ua'] = "Відправити";
+$text['label-email_response']['tr-tr'] = "Cevap";
+$text['label-email_response']['zh-cn'] = "回复";
+$text['label-email_response']['ja-jp'] = "応答";
+$text['label-email_response']['ko-kr'] = "응답";
+
+$text['label-email_retry_count']['en-us'] = "Retry";
+$text['label-email_retry_count']['en-gb'] = "Retry";
+$text['label-email_retry_count']['ar-eg'] = "إعادة الفحص";
+$text['label-email_retry_count']['de-at'] = "Wiederkehr";
+$text['label-email_retry_count']['de-ch'] = "Wiederkehr";
+$text['label-email_retry_count']['de-de'] = "Wiederkehr";
+$text['label-email_retry_count']['el-gr'] = "Ξαναδοκιμάσετε";
+$text['label-email_retry_count']['es-cl'] = "retry";
+$text['label-email_retry_count']['es-mx'] = "retry";
+$text['label-email_retry_count']['fr-ca'] = "retry";
+$text['label-email_retry_count']['fr-fr'] = "retry";
+$text['label-email_retry_count']['he-il'] = "מחדש";
+$text['label-email_retry_count']['it-it'] = "Reazione";
+$text['label-email_retry_count']['ka-ge'] = "თავიდან ცდა";
+$text['label-email_retry_count']['nl-nl'] = "Retour";
+$text['label-email_retry_count']['pl-pl'] = "retry";
+$text['label-email_retry_count']['pt-br'] = "Repito";
+$text['label-email_retry_count']['pt-pt'] = "Repito";
+$text['label-email_retry_count']['ro-ro'] = "Reîncercați";
+$text['label-email_retry_count']['ru-ru'] = "Rery";
+$text['label-email_retry_count']['sv-se'] = "Retry";
+$text['label-email_retry_count']['uk-ua'] = "Ретри";
+$text['label-email_retry_count']['tr-tr'] = "Yeniden dene";
+$text['label-email_retry_count']['zh-cn'] = "重试";
+$text['label-email_retry_count']['ja-jp'] = "リトライ";
+$text['label-email_retry_count']['ko-kr'] = "다시 해 보다";
+
+$text['description-email_retry_count']['en-us'] = "Enter the email retry.";
+$text['description-email_retry_count']['en-gb'] = "Enter the email retry.";
+$text['description-email_retry_count']['ar-eg'] = "أدخلي إعادة البريد الإلكتروني";
+$text['description-email_retry_count']['de-at'] = "Geben Sie die E-Mail-Retry ein.";
+$text['description-email_retry_count']['de-ch'] = "Geben Sie die E-Mail-Retry ein.";
+$text['description-email_retry_count']['de-de'] = "Geben Sie die E-Mail-Retry ein.";
+$text['description-email_retry_count']['el-gr'] = "Εισαγάγετε την επανάληψη του email.";
+$text['description-email_retry_count']['es-cl'] = "Ingrese el email retry.";
+$text['description-email_retry_count']['es-mx'] = "Ingrese el email retry.";
+$text['description-email_retry_count']['fr-ca'] = "Entrez le courrier électronique.";
+$text['description-email_retry_count']['fr-fr'] = "Entrez le courrier électronique.";
+$text['description-email_retry_count']['he-il'] = "הזן את דואר אלקטרוני retry.";
+$text['description-email_retry_count']['it-it'] = "Inserire l'email retry.";
+$text['description-email_retry_count']['ka-ge'] = "შეიყვანეთ ელფოსტის თავიდან ცდა.";
+$text['description-email_retry_count']['nl-nl'] = "Voer de e-mail in.";
+$text['description-email_retry_count']['pl-pl'] = "Wstęp do retrygi mailowej.";
+$text['description-email_retry_count']['pt-br'] = "Insira o e-mail retry.";
+$text['description-email_retry_count']['pt-pt'] = "Insira o e-mail retry.";
+$text['description-email_retry_count']['ro-ro'] = "Introduceți reîncercarea de e-mail.";
+$text['description-email_retry_count']['ru-ru'] = "Введите электронный ответ.";
+$text['description-email_retry_count']['sv-se'] = "Ange e-post retry.";
+$text['description-email_retry_count']['uk-ua'] = "Введіть адресу електронної пошти.";
+$text['description-email_retry_count']['tr-tr'] = "E-posta yeniden denemesini girin.";
+$text['description-email_retry_count']['zh-cn'] = "输入电子邮件重试。";
+$text['description-email_retry_count']['ja-jp'] = "メールの再試行を入力します。";
+$text['description-email_retry_count']['ko-kr'] = "이메일 재시도를 입력하십시오.";
+
+$text['label-waiting']['en-us'] = "waiting";
+$text['label-waiting']['en-gb'] = "waiting";
+$text['label-waiting']['ar-eg'] = "الانتظار";
+$text['label-waiting']['de-at'] = "warten";
+$text['label-waiting']['de-ch'] = "warten";
+$text['label-waiting']['de-de'] = "warten";
+$text['label-waiting']['el-gr'] = "αναμονή";
+$text['label-waiting']['es-cl'] = "esperando";
+$text['label-waiting']['es-mx'] = "esperando";
+$text['label-waiting']['fr-ca'] = "attendre";
+$text['label-waiting']['fr-fr'] = "attendre";
+$text['label-waiting']['he-il'] = "לחכות";
+$text['label-waiting']['it-it'] = "attesa";
+$text['label-waiting']['ka-ge'] = "მოლოდინი";
+$text['label-waiting']['nl-nl'] = "wachten.";
+$text['label-waiting']['pl-pl'] = "poczekalnia";
+$text['label-waiting']['pt-br'] = "esperando";
+$text['label-waiting']['pt-pt'] = "esperando";
+$text['label-waiting']['ro-ro'] = "aşteptare";
+$text['label-waiting']['ru-ru'] = "ждать";
+$text['label-waiting']['sv-se'] = "väntar";
+$text['label-waiting']['uk-ua'] = "Зареєструватися";
+$text['label-waiting']['tr-tr'] = "beklemek";
+$text['label-waiting']['zh-cn'] = "等待";
+$text['label-waiting']['ja-jp'] = "待っている";
+$text['label-waiting']['ko-kr'] = "대기 중";
+
+$text['label-failed']['en-us'] = "failed";
+$text['label-failed']['en-gb'] = "failed";
+$text['label-failed']['ar-eg'] = "فشل";
+$text['label-failed']['de-at'] = "gescheitert";
+$text['label-failed']['de-ch'] = "gescheitert";
+$text['label-failed']['de-de'] = "gescheitert";
+$text['label-failed']['el-gr'] = "απέτυχε";
+$text['label-failed']['es-cl'] = "fallado";
+$text['label-failed']['es-mx'] = "fallado";
+$text['label-failed']['fr-ca'] = "échoué";
+$text['label-failed']['fr-fr'] = "échoué";
+$text['label-failed']['he-il'] = "נכשל";
+$text['label-failed']['it-it'] = "fallito";
+$text['label-failed']['ka-ge'] = "ჩავარდა";
+$text['label-failed']['nl-nl'] = "Gefaald.";
+$text['label-failed']['pl-pl'] = "nieudany";
+$text['label-failed']['pt-br'] = "falhou";
+$text['label-failed']['pt-pt'] = "falhou";
+$text['label-failed']['ro-ro'] = "a eșuat";
+$text['label-failed']['ru-ru'] = "неудача";
+$text['label-failed']['sv-se'] = "Misslyckades";
+$text['label-failed']['uk-ua'] = "не вдалося";
+$text['label-failed']['tr-tr'] = "arızalı";
+$text['label-failed']['zh-cn'] = "失败的";
+$text['label-failed']['ja-jp'] = "失敗した";
+$text['label-failed']['ko-kr'] = "실패한";
+
+$text['label-sent']['en-us'] = "sent";
+$text['label-sent']['en-gb'] = "sent";
+$text['label-sent']['ar-eg'] = "أرسلت";
+$text['label-sent']['de-at'] = "gesendet";
+$text['label-sent']['de-ch'] = "gesendet";
+$text['label-sent']['de-de'] = "gesendet";
+$text['label-sent']['el-gr'] = "Απεσταλμένα";
+$text['label-sent']['es-cl'] = "enviado";
+$text['label-sent']['es-mx'] = "enviado";
+$text['label-sent']['fr-ca'] = "envoyé";
+$text['label-sent']['fr-fr'] = "envoyé";
+$text['label-sent']['he-il'] = "שלח";
+$text['label-sent']['it-it'] = "inviato";
+$text['label-sent']['ka-ge'] = "გაგზავნილია";
+$text['label-sent']['nl-nl'] = "Vertaling:";
+$text['label-sent']['pl-pl'] = "wysyłać";
+$text['label-sent']['pt-br'] = "enviado";
+$text['label-sent']['pt-pt'] = "enviado";
+$text['label-sent']['ro-ro'] = "trimis";
+$text['label-sent']['ru-ru'] = "отправление";
+$text['label-sent']['sv-se'] = "skickas";
+$text['label-sent']['uk-ua'] = "Увійти";
+$text['label-sent']['tr-tr'] = "gönderilmiş";
+$text['label-sent']['zh-cn'] = "发送";
+$text['label-sent']['ja-jp'] = "送信済";
+$text['label-sent']['ko-kr'] = "전송된";
+
+$text['label-trying']['en-us'] = "trying";
+$text['label-trying']['en-gb'] = "trying";
+$text['label-trying']['ar-eg'] = "محاولة";
+$text['label-trying']['de-at'] = "versuchen";
+$text['label-trying']['de-ch'] = "versuchen";
+$text['label-trying']['de-de'] = "versuchen";
+$text['label-trying']['el-gr'] = "προσπαθεί";
+$text['label-trying']['es-cl'] = "intentando";
+$text['label-trying']['es-mx'] = "intentando";
+$text['label-trying']['fr-ca'] = "essayer d'essayer";
+$text['label-trying']['fr-fr'] = "essayer d'essayer";
+$text['label-trying']['he-il'] = "מנסה לנסות";
+$text['label-trying']['it-it'] = "provare";
+$text['label-trying']['ka-ge'] = "მცდელობა";
+$text['label-trying']['nl-nl'] = "proberen";
+$text['label-trying']['pl-pl'] = "próbować";
+$text['label-trying']['pt-br'] = "tentando tentar";
+$text['label-trying']['pt-pt'] = "tentando tentar";
+$text['label-trying']['ro-ro'] = "încercând";
+$text['label-trying']['ru-ru'] = "попробовать";
+$text['label-trying']['sv-se'] = "försöker försöka";
+$text['label-trying']['uk-ua'] = "Навігація";
+$text['label-trying']['tr-tr'] = "denemek";
+$text['label-trying']['zh-cn'] = "试";
+$text['label-trying']['ja-jp'] = "試しています";
+$text['label-trying']['ko-kr'] = "견딜 수 없는";
+
+$text['button-test']['en-us'] = "Test";
+$text['button-test']['en-gb'] = "Test";
+$text['button-test']['ar-eg'] = "الاختبار";
+$text['button-test']['de-at'] = "Prüfung";
+$text['button-test']['de-ch'] = "Prüfung";
+$text['button-test']['de-de'] = "Prüfung";
+$text['button-test']['el-gr'] = "Δοκιμή";
+$text['button-test']['es-cl'] = "Prueba";
+$text['button-test']['es-mx'] = "Prueba";
+$text['button-test']['fr-ca'] = "Test";
+$text['button-test']['fr-fr'] = "Test";
+$text['button-test']['he-il'] = "מבחן";
+$text['button-test']['it-it'] = "test di prova";
+$text['button-test']['ka-ge'] = "შემოწმება";
+$text['button-test']['nl-nl'] = "Test";
+$text['button-test']['pl-pl'] = "test";
+$text['button-test']['pt-br'] = "Teste de teste";
+$text['button-test']['pt-pt'] = "Teste de teste";
+$text['button-test']['ro-ro'] = "Test";
+$text['button-test']['ru-ru'] = "Испытания";
+$text['button-test']['sv-se'] = "Testa test";
+$text['button-test']['uk-ua'] = "Тести";
+$text['button-test']['tr-tr'] = "Ölçek";
+$text['button-test']['zh-cn'] = "测试";
+$text['button-test']['ja-jp'] = "テスト";
+$text['button-test']['ko-kr'] = "시험";
+
+$text['header-email_test']['en-us'] = "Email Test";
+$text['header-email_test']['en-gb'] = "Email Test";
+$text['header-email_test']['ar-eg'] = "اختبار البريد الإلكتروني";
+$text['header-email_test']['de-at'] = "E-Mail-Test";
+$text['header-email_test']['de-ch'] = "E-Mail-Test";
+$text['header-email_test']['de-de'] = "E-Mail-Test";
+$text['header-email_test']['el-gr'] = "Δοκιμή ηλεκτρονικού ταχυδρομείου";
+$text['header-email_test']['es-cl'] = "Prueba de correo electrónico";
+$text['header-email_test']['es-mx'] = "Prueba de correo electrónico";
+$text['header-email_test']['fr-ca'] = "Test de messagerie";
+$text['header-email_test']['fr-fr'] = "Test de messagerie";
+$text['header-email_test']['he-il'] = 'מבחן דוא"ל';
+$text['header-email_test']['it-it'] = "E-mail di prova";
+$text['header-email_test']['ka-ge'] = "ელფოსტის შემოწმება";
+$text['header-email_test']['nl-nl'] = "E-mailtest";
+$text['header-email_test']['pl-pl'] = "Test e-maila";
+$text['header-email_test']['pt-br'] = "Teste de e-mail";
+$text['header-email_test']['pt-pt'] = "Teste de e-mail";
+$text['header-email_test']['ro-ro'] = "Test de e-mail";
+$text['header-email_test']['ru-ru'] = "Тест электронной почты";
+$text['header-email_test']['sv-se'] = "E-posttest";
+$text['header-email_test']['uk-ua'] = "Тест електронної пошти";
+$text['header-email_test']['tr-tr'] = "E-posta Testi";
+$text['header-email_test']['zh-cn'] = "电子邮件测试";
+$text['header-email_test']['ja-jp'] = "メールテスト";
+$text['header-email_test']['ko-kr'] = "이메일 테스트";
+
+$text['header-settings']['en-us'] = "Settings";
+$text['header-settings']['en-gb'] = "Settings";
+$text['header-settings']['ar-eg'] = "الترتيبات";
+$text['header-settings']['de-at'] = "Einstellungen";
+$text['header-settings']['de-ch'] = "Einstellungen";
+$text['header-settings']['de-de'] = "Einstellungen";
+$text['header-settings']['el-gr'] = "Ρυθμίσεις";
+$text['header-settings']['es-cl'] = "Ajustes";
+$text['header-settings']['es-mx'] = "Ajustes";
+$text['header-settings']['fr-ca'] = "Paramètres";
+$text['header-settings']['fr-fr'] = "Paramètres";
+$text['header-settings']['he-il'] = "הגדרות הגדרות";
+$text['header-settings']['it-it'] = "Impostazioni impostazioni";
+$text['header-settings']['ka-ge'] = "მორგება";
+$text['header-settings']['nl-nl'] = "Instellingen";
+$text['header-settings']['pl-pl'] = "Setting";
+$text['header-settings']['pt-br'] = "Configurações";
+$text['header-settings']['pt-pt'] = "Configurações";
+$text['header-settings']['ro-ro'] = "Setări";
+$text['header-settings']['ru-ru'] = "Настройка";
+$text['header-settings']['sv-se'] = "Inställningar";
+$text['header-settings']['uk-ua'] = "Налаштування";
+$text['header-settings']['tr-tr'] = "Ayarlar";
+$text['header-settings']['zh-cn'] = "设置";
+$text['header-settings']['ja-jp'] = "設定";
+$text['header-settings']['ko-kr'] = "설정";
+
+$text['header-connection']['en-us'] = "Connection";
+$text['header-connection']['en-gb'] = "Connection";
+$text['header-connection']['ar-eg'] = "الاتصال";
+$text['header-connection']['de-at'] = "Verbindung";
+$text['header-connection']['de-ch'] = "Verbindung";
+$text['header-connection']['de-de'] = "Verbindung";
+$text['header-connection']['el-gr'] = "Σύνδεση";
+$text['header-connection']['es-cl'] = "Conexión";
+$text['header-connection']['es-mx'] = "Conexión";
+$text['header-connection']['fr-ca'] = "Connexion";
+$text['header-connection']['fr-fr'] = "Connexion";
+$text['header-connection']['he-il'] = "חיבור";
+$text['header-connection']['it-it'] = "Connessione";
+$text['header-connection']['ka-ge'] = "დაკავშირება";
+$text['header-connection']['nl-nl'] = "Verbinding";
+$text['header-connection']['pl-pl'] = "połączenie";
+$text['header-connection']['pt-br'] = "Conexão";
+$text['header-connection']['pt-pt'] = "Conexão";
+$text['header-connection']['ro-ro'] = "Conexiune";
+$text['header-connection']['ru-ru'] = "Подключение";
+$text['header-connection']['sv-se'] = "Anslutning";
+$text['header-connection']['uk-ua'] = "Підключення";
+$text['header-connection']['tr-tr'] = "Bağlantı";
+$text['header-connection']['zh-cn'] = "联系";
+$text['header-connection']['ja-jp'] = "繋がり";
+$text['header-connection']['ko-kr'] = "연결";
+
+$text['header-result']['en-us'] = "Result";
+$text['header-result']['en-gb'] = "Result";
+$text['header-result']['ar-eg'] = "النتيجة";
+$text['header-result']['de-at'] = "Ergebnis";
+$text['header-result']['de-ch'] = "Ergebnis";
+$text['header-result']['de-de'] = "Ergebnis";
+$text['header-result']['el-gr'] = "Αποτέλεσμα";
+$text['header-result']['es-cl'] = "Resultado";
+$text['header-result']['es-mx'] = "Resultado";
+$text['header-result']['fr-ca'] = "Résultat ";
+$text['header-result']['fr-fr'] = "Résultat ";
+$text['header-result']['he-il'] = "תוצאה";
+$text['header-result']['it-it'] = "Risultato";
+$text['header-result']['ka-ge'] = "შედეგი";
+$text['header-result']['nl-nl'] = "Resultaat";
+$text['header-result']['pl-pl'] = "rezultat";
+$text['header-result']['pt-br'] = "Resultado";
+$text['header-result']['pt-pt'] = "Resultado";
+$text['header-result']['ro-ro'] = "Rezultat";
+$text['header-result']['ru-ru'] = "Результат";
+$text['header-result']['sv-se'] = "Resultat";
+$text['header-result']['uk-ua'] = "Почати";
+$text['header-result']['tr-tr'] = "Sonuç";
+$text['header-result']['zh-cn'] = "结果";
+$text['header-result']['ja-jp'] = "結果";
+$text['header-result']['ko-kr'] = "결과";
+
+$text['description-email_test']['en-us'] = "This is a simple test of your SMTP settings currently configured in Default or Domain Settings. Note: The message sent will not show up in the Email Queue.";
+$text['description-email_test']['en-gb'] = "This is a simple test of your SMTP settings currently configured in Default or Domain Settings. Note: The message sent will not show up in the Email Queue.";
+$text['description-email_test']['ar-eg'] = "يعد هذا اختبارًا بسيطًا لإعدادات SMTP التي تم تكوينها حاليًا في الإعدادات الافتراضية أو إعدادات المجال. ملاحظة: لن تظهر الرسالة المرسلة في قائمة انتظار البريد الإلكتروني.";
+$text['description-email_test']['de-at'] = "Dies ist ein einfacher Test Ihrer SMTP-Einstellungen, die derzeit in den Standard- oder Domäneneinstellungen konfiguriert sind. Hinweis: Die gesendete Nachricht wird nicht in der E-Mail-Warteschlange angezeigt.";
+$text['description-email_test']['de-ch'] = "Dies ist ein einfacher Test Ihrer SMTP-Einstellungen, die derzeit in den Standard- oder Domäneneinstellungen konfiguriert sind. Hinweis: Die gesendete Nachricht wird nicht in der E-Mail-Warteschlange angezeigt.";
+$text['description-email_test']['de-de'] = "Dies ist ein einfacher Test Ihrer SMTP-Einstellungen, die derzeit in den Standard- oder Domäneneinstellungen konfiguriert sind. Hinweis: Die gesendete Nachricht wird nicht in der E-Mail-Warteschlange angezeigt.";
+$text['description-email_test']['el-gr'] = "Αυτή είναι μια απλή δοκιμή των ρυθμίσεων SMTP που έχουν διαμορφωθεί αυτήν τη στιγμή στις Προεπιλεγμένες ή Ρυθμίσεις Τομέα. Σημείωση: Το μήνυμα που αποστέλλεται δεν θα εμφανιστεί στην ουρά email.";
+$text['description-email_test']['es-cl'] = "Esta es una prueba simple de la configuración SMTP actualmente configurada en Configuración predeterminada o de dominio. Nota: El mensaje enviado no aparecerá en la cola de correo electrónico.";
+$text['description-email_test']['es-mx'] = "Esta es una prueba simple de la configuración SMTP actualmente configurada en Configuración predeterminada o de dominio. Nota: El mensaje enviado no aparecerá en la cola de correo electrónico.";
+$text['description-email_test']['fr-ca'] = "Il s'agit d'un simple test de vos paramètres SMTP actuellement configurés dans les paramètres par défaut ou de domaine. Remarque : Le message envoyé n'apparaîtra pas dans la file d'attente des e-mails.";
+$text['description-email_test']['fr-fr'] = "Il s'agit d'un simple test de vos paramètres SMTP actuellement configurés dans les paramètres par défaut ou de domaine. Remarque : Le message envoyé n'apparaîtra pas dans la file d'attente des e-mails.";
+$text['description-email_test']['he-il'] = 'זוהי בדיקה פשוטה של הגדרות ה-SMTP שלך המוגדרות כעת בהגדרות ברירת מחדל או תחום. הערה: ההודעה שנשלחה לא תופיע בתור הדוא"ל.';
+$text['description-email_test']['it-it'] = "Questo è un semplice test delle tue impostazioni SMTP attualmente configurate in Impostazioni predefinite o Dominio. Nota: il messaggio inviato non verrà visualizzato nella coda e-mail.";
+$text['description-email_test']['ka-ge'] = "ეს მარტივი შემოწმებაა თქვენი SMTP პარამეტრებისთვის, რომელიც ნაგულისხმევ, ან დომენის პარამეტრებში შეიყვანეთ. შენიშვნა: გაგზავნილი შეტყობინება ელფოსტის რიგში არ გამოჩნდება.";
+$text['description-email_test']['nl-nl'] = "Dit is een eenvoudige test van uw SMTP-instellingen die momenteel zijn geconfigureerd in Standaard- of Domeininstellingen. Opmerking: het verzonden bericht verschijnt niet in de e-mailwachtrij.";
+$text['description-email_test']['pl-pl'] = "Jest to prosty test ustawień SMTP aktualnie skonfigurowanych w Ustawieniach domyślnych lub Ustawieniach domeny. Uwaga: wysłana wiadomość nie pojawi się w kolejce e-maili.";
+$text['description-email_test']['pt-br'] = "Este é um teste simples das configurações SMTP atualmente definidas nas configurações padrão ou de domínio. Nota: A mensagem enviada não aparecerá na fila de e-mail.";
+$text['description-email_test']['pt-pt'] = "Este é um teste simples das configurações SMTP atualmente definidas nas configurações padrão ou de domínio. Nota: A mensagem enviada não aparecerá na fila de e-mail.";
+$text['description-email_test']['ro-ro'] = "Acesta este un test simplu al setărilor dvs. SMTP configurate în prezent în Setări implicite sau de domeniu. Notă: mesajul trimis nu va apărea în coada de e-mail.";
+$text['description-email_test']['ru-ru'] = "Это простая проверка ваших настроек SMTP, которые в настоящее время настроены в настройках по умолчанию или в настройках домена. Примечание. Отправленное сообщение не появится в очереди электронной почты.";
+$text['description-email_test']['sv-se'] = "Detta är ett enkelt test av dina SMTP-inställningar som för närvarande är konfigurerade i standard- eller domäninställningar. Obs: Det skickade meddelandet kommer inte att visas i e-postkön.";
+$text['description-email_test']['uk-ua'] = "Це проста перевірка ваших налаштувань SMTP, налаштованих у параметрах за замовчуванням або в параметрах домену. Примітка: надіслане повідомлення не відображатиметься в черзі електронної пошти.";
+$text['description-email_test']['tr-tr'] = "Bu, halihazırda Varsayılan veya Etki Alanı Ayarlarında yapılandırılmış olan SMTP ayarlarınızın basit bir testidir. Not: Gönderilen mesaj E-posta Kuyruğunda görünmez.";
+$text['description-email_test']['zh-cn'] = "这是对默认或域设置中当前配置的 SMTP 设置的简单测试。 注意:已发送的消息不会显示在电子邮件队列中。";
+$text['description-email_test']['ja-jp'] = "これは、現在デフォルト設定またはドメイン設定で構成されている SMTP 設定の簡単なテストです。 注: 送信されたメッセージは電子メール キューには表示されません。";
+$text['description-email_test']['ko-kr'] = "이는 현재 기본 또는 도메인 설정에 구성된 SMTP 설정에 대한 간단한 테스트입니다. 참고: 전송된 메시지는 이메일 대기열에 표시되지 않습니다.";
+
+?>

+ 37 - 0
core/email_queue/app_menu.php

@@ -0,0 +1,37 @@
+<?php
+
+	$y=0;
+	$apps[$x]['menu'][$y]['title']['en-us'] = "Email Queue";
+	$apps[$x]['menu'][$y]['title']['en-gb'] = "Email Queue";
+	$apps[$x]['menu'][$y]['title']['ar-eg'] = "قائمة انتظار البريد الإلكتروني";
+	$apps[$x]['menu'][$y]['title']['de-at'] = "Email Warteschlange";
+	$apps[$x]['menu'][$y]['title']['de-ch'] = "Email Warteschlange";
+	$apps[$x]['menu'][$y]['title']['de-de'] = "Email Warteschlange";
+	$apps[$x]['menu'][$y]['title']['es-cl'] = "Correo electrónico";
+	$apps[$x]['menu'][$y]['title']['es-mx'] = "Correo electrónico";
+	$apps[$x]['menu'][$y]['title']['fr-ca'] = "Email Queue";
+	$apps[$x]['menu'][$y]['title']['fr-fr'] = "Email Queue";
+	$apps[$x]['menu'][$y]['title']['he-il'] = 'תור דוא"ל';
+	$apps[$x]['menu'][$y]['title']['it-it'] = "Coda di posta elettronica";
+	$apps[$x]['menu'][$y]['title']['ka-ge'] = "ელფოსტის რიგი";
+	$apps[$x]['menu'][$y]['title']['nl-nl'] = "Email Wachtrij";
+	$apps[$x]['menu'][$y]['title']['pl-pl'] = "Kolejka e-maili";
+	$apps[$x]['menu'][$y]['title']['pt-br'] = "Enquete de Email";
+	$apps[$x]['menu'][$y]['title']['pt-pt'] = "Enquete de Email";
+	$apps[$x]['menu'][$y]['title']['ro-ro'] = "Coada de e-mailuri";
+	$apps[$x]['menu'][$y]['title']['ru-ru'] = "Очередь электронной почты";
+	$apps[$x]['menu'][$y]['title']['sv-se'] = "E-postkö";
+	$apps[$x]['menu'][$y]['title']['uk-ua'] = "Електронна пошта";
+	$apps[$x]['menu'][$y]['title']['zh-cn'] = "电子邮件队列";
+	$apps[$x]['menu'][$y]['title']['ja-jp'] = "メールキュー";
+	$apps[$x]['menu'][$y]['title']['ko-kr'] = "이메일 대기열";
+	$apps[$x]['menu'][$y]['uuid'] = "dfa6a878-e2b0-4051-acaf-f6ffc13b9abf";
+	$apps[$x]['menu'][$y]['parent_uuid'] = "0438b504-8613-7887-c420-c837ffb20cb1";
+	$apps[$x]['menu'][$y]['category'] = "internal";
+	$apps[$x]['menu'][$y]['icon'] = "";
+	$apps[$x]['menu'][$y]['path'] = "/core/email_queue/email_queue.php";
+	$apps[$x]['menu'][$y]['order'] = "";
+	$apps[$x]['menu'][$y]['groups'][] = "superadmin";
+	$y++;
+
+?>

+ 416 - 0
core/email_queue/email_queue.php

@@ -0,0 +1,416 @@
+<?php
+/*
+	FusionPBX
+	Version: MPL 1.1
+
+	The contents of this file are subject to the Mozilla Public License Version
+	1.1 (the "License"); you may not use this file except in compliance with
+	the License. You may obtain a copy of the License at
+	http://www.mozilla.org/MPL/
+
+	Software distributed under the License is distributed on an "AS IS" basis,
+	WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+	for the specific language governing rights and limitations under the
+	License.
+
+	The Original Code is FusionPBX
+
+	The Initial Developer of the Original Code is
+	Mark J Crane <[email protected]>
+	Portions created by the Initial Developer are Copyright (C) 2022-2023
+	the Initial Developer. All Rights Reserved.
+
+	Contributor(s):
+	Mark J Crane <[email protected]>
+*/
+
+//includes files
+	require_once dirname(__DIR__, 2) . "/resources/require.php";
+	require_once "resources/check_auth.php";
+	require_once "resources/paging.php";
+
+//check permissions
+	if (permission_exists('email_queue_view')) {
+		//access granted
+	}
+	else {
+		echo "access denied";
+		exit;
+	}
+
+//add multi-lingual support
+	$language = new text;
+	$text = $language->get();
+
+//get the http post data
+	if (!empty($_POST['email_queue']) && is_array($_POST['email_queue'])) {
+		$action = $_POST['action'];
+		$search = $_POST['search'];
+		$email_queue = $_POST['email_queue'];
+	}
+
+//process the http post data by action
+	if (!empty($action) && !empty($email_queue) && is_array($email_queue) && @sizeof($email_queue) != 0) {
+
+		//validate the token
+		$token = new token;
+		if (!$token->validate($_SERVER['PHP_SELF'])) {
+			message::add($text['message-invalid_token'],'negative');
+			header('Location: email_queue.php');
+			exit;
+		}
+
+		//prepare the array
+		$x = 0;
+		foreach ($email_queue as $row) {
+			//email class queue uuid
+			$array[$x]['checked'] = $row['checked'] ?? null;
+			$array[$x]['uuid'] = $row['email_queue_uuid'];
+
+			// database class uuid
+			//$array['email_queue'][$x]['checked'] = $row['checked'];
+			//$array['email_queue'][$x]['email_queue_uuid'] = $row['email_queue_uuid'];
+			$x++;
+		}
+
+		//prepare the database object
+		$database = new database;
+		$database->app_name = 'email_queue';
+		$database->app_uuid = '5befdf60-a242-445f-91b3-2e9ee3e0ddf7';
+
+		//send the array to the database class
+		switch ($action) {
+			case 'copy':
+				//if (permission_exists('email_queue_add')) {
+				//	$database->copy($array);
+				//}
+				break;
+			case 'toggle':
+				//if (permission_exists('email_queue_edit')) {
+				//	$database->toggle($array);
+				//}
+				break;
+			case 'delete':
+				if (permission_exists('email_queue_delete')) {
+					$obj = new email_queue;
+					$obj->delete($array);
+					//$database->delete($array);
+				}
+				break;
+		}
+
+		//redirect the user
+		header('Location: email_queue.php'.($search != '' ? '?search='.urlencode($search) : null));
+		exit;
+	}
+
+//set the time zone
+	if (isset($_SESSION['domain']['time_zone']['name'])) {
+		$time_zone = $_SESSION['domain']['time_zone']['name'];
+	}
+	else {
+		$time_zone = date_default_timezone_get();
+	}
+
+//get order and order by
+	$order_by = $_GET["order_by"] ?? null;
+	$order = $_GET["order"] ?? null;
+
+//add the search
+	if (isset($_GET["search"])) {
+		$search = strtolower($_GET["search"]);
+	}
+
+//get the count
+	$sql = "select count(email_queue_uuid) ";
+	$sql .= "from v_email_queue ";
+	$sql .= "where true ";
+	if (isset($search)) {
+		$sql .= "and (";
+		$sql .= "	lower(email_from) like :search ";
+		$sql .= "	or lower(email_to) like :search ";
+		$sql .= "	or lower(email_subject) like :search ";
+		$sql .= "	or lower(email_body) like :search ";
+		$sql .= "	or lower(email_status) like :search ";
+		$sql .= ") ";
+		$parameters['search'] = '%'.$search.'%';
+	}
+	if (isset($_GET["email_status"]) && $_GET["email_status"] != '') {
+		$sql .= "and email_status = :email_status ";
+		$parameters['email_status'] = $_GET["email_status"];
+	}
+	//else {
+	//	$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
+	//	$parameters['domain_uuid'] = $domain_uuid;
+	//}
+	$database = new database;
+	$num_rows = $database->select($sql, $parameters ?? null, 'column');
+	unset($sql, $parameters);
+
+//prepare to page the results
+	$rows_per_page = ($_SESSION['domain']['paging']['numeric'] != '') ? $_SESSION['domain']['paging']['numeric'] : 50;
+	$param = !empty($_GET["email_status"]) ? "&email_status=".urlencode($_GET["email_status"]) : null;
+	$param .= !empty($search) ? "&search=".urlencode($search) : null;
+	$param .= !empty($_REQUEST['show']) && $_REQUEST['show'] == 'all' && permission_exists('email_queue_all') ? "&show=all" : null;
+	$page = !empty($_REQUEST['page']) && is_numeric($_REQUEST['page']) ? $_REQUEST['page'] : 0;
+	list($paging_controls, $rows_per_page) = paging($num_rows, $param, $rows_per_page);
+	list($paging_controls_mini, $rows_per_page) = paging($num_rows, $param, $rows_per_page, true);
+	$offset = $rows_per_page * $page;
+
+//get the list
+	$sql = "select ";
+	$sql .= "email_date, ";
+	$sql .= "to_char(timezone(:time_zone, email_date), 'DD Mon YYYY') as email_date_formatted, \n";
+	$sql .= "to_char(timezone(:time_zone, email_date), 'HH12:MI:SS am') as email_time_formatted, \n";
+	$sql .= "email_queue_uuid, ";
+	$sql .= "hostname, ";
+	$sql .= "email_from, ";
+	$sql .= "email_to, ";
+	$sql .= "email_subject, ";
+	$sql .= "substring(email_body, 0, 80) as email_body, ";
+	//$sql .= "email_action_before, ";
+	$sql .= "email_action_after, ";
+	$sql .= "email_status, ";
+	$sql .= "email_retry_count ";
+	$sql .= "from v_email_queue ";
+	$sql .= "where true ";
+	if (isset($search)) {
+		$sql .= "and (";
+		$sql .= "	lower(email_from) like :search ";
+		$sql .= "	or lower(email_to) like :search ";
+		$sql .= "	or lower(email_subject) like :search ";
+		$sql .= "	or lower(email_body) like :search ";
+		$sql .= "	or lower(email_status) like :search ";
+		$sql .= ") ";
+		$parameters['search'] = '%'.$search.'%';
+	}
+	if (isset($_GET["email_status"]) && $_GET["email_status"] != '') {
+		$sql .= "and email_status = :email_status ";
+		$parameters['email_status'] = $_GET["email_status"];
+	}
+	$sql .= order_by($order_by, $order, 'email_date', 'desc');
+	$sql .= limit_offset($rows_per_page, $offset);
+	$parameters['time_zone'] = $time_zone;
+	$database = new database;
+	$email_queue = $database->select($sql, $parameters, 'all');
+	unset($sql, $parameters);
+
+//create token
+	$object = new token;
+	$token = $object->create('/app/email_queue/email_queue.php');
+
+//additional includes
+	$document['title'] = $text['title-email_queue'];
+	require_once "resources/header.php";
+
+//test result layer
+	echo "<style>\n";
+	echo "	#test_result_layer {\n";
+	echo "		z-index: 999999;\n";
+	echo "		position: absolute;\n";
+	echo "		left: 0px;\n";
+	echo "		top: 0px;\n";
+	echo "		right: 0px;\n";
+	echo "		bottom: 0px;\n";
+	echo "		text-align: center;\n";
+	echo "		vertical-align: middle;\n";
+	echo "		}\n";
+	echo "	#test_result_container {\n";
+	echo "		display: block;\n";
+	echo "		overflow: auto;\n";
+	echo "		background-color: #fff;\n";
+	echo "		padding: 25px 25px;\n";
+	if (http_user_agent('mobile')) {
+		echo "	margin: 0;\n";
+	}
+	else {
+		echo "	margin: auto 10%;\n";
+	}
+	echo "		text-align: left;\n";
+	echo "		-webkit-box-shadow: 0px 1px 20px #888;\n";
+	echo "		-moz-box-shadow: 0px 1px 20px #888;\n";
+	echo "		box-shadow: 0px 1px 20px #888;\n";
+	echo "		}\n";
+	echo "</style>\n";
+
+	echo "<div id='test_result_layer' style='display: none;'>\n";
+	echo "	<table cellpadding='0' cellspacing='0' border='0' width='100%' height='100%'>\n";
+	echo "		<tr>\n";
+	echo "			<td align='center' valign='middle'>\n";
+	echo "				<span id='test_result_container'></span>\n";
+	echo "			</td>\n";
+	echo "		</tr>\n";
+	echo "	</table>\n";
+	echo "</div>\n";
+
+//show the content
+	echo "<div class='action_bar' id='action_bar'>\n";
+	echo "	<div class='heading'><b>".$text['title-email_queue']."</b><div class='count'>".number_format($num_rows)."</div></div>\n";
+	echo "	<div class='actions'>\n";
+	//if (permission_exists('email_queue_add')) {
+	//	echo button::create(['type'=>'button','label'=>$text['button-add'],'icon'=>$_SESSION['theme']['button_icon_add'],'id'=>'btn_add','name'=>'btn_add','link'=>'email_queue_edit.php']);
+	//}
+	//if (permission_exists('email_queue_add') && $email_queue) {
+	//	echo button::create(['type'=>'button','label'=>$text['button-copy'],'icon'=>$_SESSION['theme']['button_icon_copy'],'id'=>'btn_copy','name'=>'btn_copy','style'=>'display:none;','onclick'=>"modal_open('modal-copy','btn_copy');"]);
+	//}
+	//if (permission_exists('email_queue_edit') && $email_queue) {
+	//	echo button::create(['type'=>'button','label'=>$text['button-toggle'],'icon'=>$_SESSION['theme']['button_icon_toggle'],'id'=>'btn_toggle','name'=>'btn_toggle','style'=>'display:none;','onclick'=>"modal_open('modal-toggle','btn_toggle');"]);
+	//}
+	echo 		"<form id='form_test' class='inline' method='post' action='email_test.php' target='_blank'>\n";
+	echo button::create(['label'=>$text['button-test'],'icon'=>'tools','type'=>'button','id'=>'test_button','style'=>'margin-right: 15px;','onclick'=>"$(this).fadeOut(400, function(){ $('span#form_test').fadeIn(400); $('#to').trigger('focus'); });"]);
+	echo "		<span id='form_test' style='display: none;'>\n";
+	echo "			<input type='text' class='txt' style='width: 150px;' name='to' id='to' placeholder='[email protected]'>";
+	echo button::create(['label'=>$text['button-send'],'icon'=>'envelope','type'=>'submit','id'=>'send_button','style'=>'margin-right: 15px;']);
+	echo "		</span>\n";
+	echo "		</form>";
+	if (permission_exists('email_queue_delete') && $email_queue) {
+		echo button::create(['type'=>'button','label'=>$text['button-delete'],'icon'=>$_SESSION['theme']['button_icon_delete'],'id'=>'btn_delete','name'=>'btn_delete','style'=>'display:none;','onclick'=>"modal_open('modal-delete','btn_delete');"]);
+	}
+	echo "		<form id='form_search' class='inline' method='get'>\n";
+	echo "		<select class='formfld' name='email_status'>\n";
+    echo "			<option value='' selected='selected' disabled hidden>".$text['label-email_status']."...</option>";
+	echo "			<option value=''></option>\n";
+	echo "			<option value='waiting' ".(!empty($_GET["email_status"]) && $_GET["email_status"] == "waiting" ? "selected='selected'" : null).">".ucwords($text['label-waiting'])."</option>\n";
+	echo "			<option value='trying' ".(!empty($_GET["email_status"]) && $_GET["email_status"] == "trying" ? "selected='selected'" : null).">".ucwords($text['label-trying'])."</option>\n";
+	echo "			<option value='sent' ".(!empty($_GET["email_status"]) && $_GET["email_status"] == "sent" ? "selected='selected'" : null).">".ucwords($text['label-sent'])."</option>\n";
+	echo "			<option value='failed' ".(!empty($_GET["email_status"]) && $_GET["email_status"] == "failed" ? "selected='selected'" : null).">".ucwords($text['label-failed'])."</option>\n";
+	echo "		</select>\n";
+	//if (permission_exists('email_queue_all')) {
+	//	if ($_GET['show'] == 'all') {
+	//		echo "		<input type='hidden' name='show' value='all'>\n";
+	//	}
+	//	else {
+	//		echo button::create(['type'=>'button','label'=>$text['button-show_all'],'icon'=>$_SESSION['theme']['button_icon_all'],'link'=>'?show=all']);
+	//	}
+	//}
+	echo 		"<input type='text' class='txt list-search' name='search' id='search' value=\"".escape($search ?? '')."\" placeholder=\"".$text['label-search']."\" />";
+	echo button::create(['label'=>$text['button-search'],'icon'=>$_SESSION['theme']['button_icon_search'],'type'=>'submit','id'=>'btn_search']);
+	if ($paging_controls_mini != '') {
+		echo 	"<span style='margin-left: 15px;'>".$paging_controls_mini."</span>\n";
+	}
+	echo "		</form>\n";
+	echo "	</div>\n";
+	echo "	<div style='clear: both;'></div>\n";
+	echo "</div>\n";
+
+	if (permission_exists('email_queue_add') && $email_queue) {
+		echo modal::create(['id'=>'modal-copy','type'=>'copy','actions'=>button::create(['type'=>'button','label'=>$text['button-continue'],'icon'=>'check','id'=>'btn_copy','style'=>'float: right; margin-left: 15px;','collapse'=>'never','onclick'=>"modal_close(); list_action_set('copy'); list_form_submit('form_list');"])]);
+	}
+	if (permission_exists('email_queue_edit') && $email_queue) {
+		echo modal::create(['id'=>'modal-toggle','type'=>'toggle','actions'=>button::create(['type'=>'button','label'=>$text['button-continue'],'icon'=>'check','id'=>'btn_toggle','style'=>'float: right; margin-left: 15px;','collapse'=>'never','onclick'=>"modal_close(); list_action_set('toggle'); list_form_submit('form_list');"])]);
+	}
+	if (permission_exists('email_queue_delete') && $email_queue) {
+		echo modal::create(['id'=>'modal-delete','type'=>'delete','actions'=>button::create(['type'=>'button','label'=>$text['button-continue'],'icon'=>'check','id'=>'btn_delete','style'=>'float: right; margin-left: 15px;','collapse'=>'never','onclick'=>"modal_close(); list_action_set('delete'); list_form_submit('form_list');"])]);
+	}
+
+	echo "<form id='form_list' method='post'>\n";
+	echo "<input type='hidden' id='action' name='action' value=''>\n";
+	echo "<input type='hidden' name='search' value=\"".escape($search ?? '')."\">\n";
+
+	echo "<div class='card'>\n";
+	echo "<table class='list'>\n";
+	echo "<tr class='list-header'>\n";
+	if (permission_exists('email_queue_add') || permission_exists('email_queue_edit') || permission_exists('email_queue_delete')) {
+		echo "	<th class='checkbox'>\n";
+		echo "		<input type='checkbox' id='checkbox_all' name='checkbox_all' onclick='list_all_toggle(); checkbox_on_change(this);' ".(empty($email_queue) ? "style='visibility: hidden;'" : null).">\n";
+		echo "	</th>\n";
+	}
+	//if ($_GET['show'] == 'all' && permission_exists('email_queue_all')) {
+	//	echo th_order_by('domain_name', $text['label-domain'], $order_by, $order);
+	//}
+	//echo th_order_by('email_date', $text['label-email_date'], $order_by, $order);
+	echo "<th class='center shrink'>".$text['label-date']."</th>\n";
+	echo "<th class='center shrink hide-md-dn'>".$text['label-time']."</th>\n";
+	echo "<th class='shrink hide-md-dn'>".$text['label-hostname']."</th>\n";
+	echo "<th class='shrink hide-md-dn'>".$text['label-email_from']."</th>\n";
+	echo th_order_by('email_to', $text['label-email_to'], $order_by, $order);
+	echo th_order_by('email_subject', $text['label-email_subject'], $order_by, $order);
+	echo th_order_by('email_status', $text['label-email_status'], $order_by, $order);
+	echo th_order_by('email_retry_count', $text['label-email_retry_count'], $order_by, $order);
+	//echo th_order_by('email_action_before', $text['label-email_action_before'], $order_by, $order);
+	echo "<th class='hide-md-dn'>".$text['label-email_action_after']."</th>\n";
+	if (permission_exists('email_queue_edit') && !empty($_SESSION['theme']['list_row_edit_button']['boolean']) && $_SESSION['theme']['list_row_edit_button']['boolean'] == 'true') {
+		echo "	<td class='action-button'>&nbsp;</td>\n";
+	}
+	echo "</tr>\n";
+
+	if (is_array($email_queue) && @sizeof($email_queue) != 0) {
+		$x = 0;
+		foreach ($email_queue as $row) {
+			if (permission_exists('email_queue_edit')) {
+				$list_row_url = "email_queue_edit.php?id=".urlencode($row['email_queue_uuid']);
+			}
+			echo "<tr class='list-row' href='".$list_row_url."'>\n";
+			if (permission_exists('email_queue_add') || permission_exists('email_queue_edit') || permission_exists('email_queue_delete')) {
+				echo "	<td class='checkbox'>\n";
+				echo "		<input type='checkbox' name='email_queue[$x][checked]' id='checkbox_".$x."' value='true' onclick=\"checkbox_on_change(this); if (!this.checked) { document.getElementById('checkbox_all').checked = false; }\">\n";
+				echo "		<input type='hidden' name='email_queue[$x][email_queue_uuid]' value='".escape($row['email_queue_uuid'])."' />\n";
+				echo "	</td>\n";
+			}
+			//if ($_GET['show'] == 'all' && permission_exists('email_queue_all')) {
+			//	echo "	<td>".escape($_SESSION['domains'][$row['domain_uuid']]['domain_name'])."</td>\n";
+			//}
+			if (permission_exists('email_queue_edit')) {
+				//echo "	<td><a href='".$list_row_url."' title=\"".$text['button-edit']."\">".escape($row['email_date'])."</a></td>\n";
+				echo "	<td nowrap='nowrap'><a href='".$list_row_url."' title=\"".$text['button-edit']."\">".escape($row['email_date_formatted'])."</a></td>\n";
+				echo "	<td nowrap='nowrap' class='center shrink hide-md-dn'><a href='".$list_row_url."' title=\"".$text['button-edit']."\">".escape($row['email_time_formatted'])."</a></td>\n";
+			}
+			else {
+				//echo "	<td>".escape($row['email_date'])."	</td>\n";
+				echo "	<td nowrap='nowrap'>".escape($row['email_date_formatted'])."	</td>\n";
+				echo "	<td nowrap='nowrap'>".escape($row['email_time_formatted'])."	</td>\n";
+			}
+			echo "	<td class='hide-md-dn'>".escape($row['hostname'])."</td>\n";
+			echo "	<td class='shrink hide-md-dn'>".escape($row['email_from'])."</td>\n";
+			echo "	<td class='overflow' style='width: 20%; max-width: 200px;'>".escape($row['email_to'])."</td>\n";
+			echo "	<td class='overflow' style='width: 30%; max-width: 200px;'>".iconv_mime_decode($row['email_subject'])."</td>\n";
+// 			echo "	<td class='hide-md-dn'>".escape($row['email_body'])."</td>\n";
+			echo "	<td>".ucwords($text['label-'.$row['email_status']])."</td>\n";
+			echo "	<td>".escape($row['email_retry_count'])."</td>\n";
+			//echo "	<td>".escape($row['email_action_before'])."</td>\n";
+			echo "	<td class='hide-md-dn'>".escape($row['email_action_after'])."</td>\n";
+			if (permission_exists('email_queue_edit') && !empty($_SESSION['theme']['list_row_edit_button']['boolean']) && $_SESSION['theme']['list_row_edit_button']['boolean'] == 'true') {
+				echo "	<td class='action-button'>\n";
+				echo button::create(['type'=>'button','title'=>$text['button-edit'],'icon'=>$_SESSION['theme']['button_icon_edit'],'link'=>$list_row_url]);
+				echo "	</td>\n";
+			}
+			echo "</tr>\n";
+			$x++;
+		}
+		unset($email_queue);
+	}
+
+	echo "</table>\n";
+	echo "</div>\n";
+	echo "<br />\n";
+	echo "<div align='center'>".$paging_controls."</div>\n";
+	echo "<input type='hidden' name='".$token['name']."' value='".$token['hash']."'>\n";
+	echo "</form>\n";
+
+//test script
+	echo "<script>\n";
+	echo "	$('#form_test').submit(function(event) {\n";
+	echo "		event.preventDefault();\n";
+	echo "		$.ajax({\n";
+	echo "			url: $(this).attr('action'),\n";
+	echo "			type: $(this).attr('method'),\n";
+	echo "			data: new FormData(this),\n";
+	echo "			processData: false,\n";
+	echo "			contentType: false,\n";
+	echo "			cache: false,\n";
+	echo "			success: function(response){\n";
+	echo "				$('#test_result_container').html(response);\n";
+	echo "				$('#test_result_layer').fadeIn(400);\n";
+	echo "				$('span#form_test').fadeOut(400, function(){\n";
+	echo "					$('#test_button').fadeIn(400);\n";
+	echo "					$('#to').val('');\n";
+	echo "				});\n";
+	echo "			}\n";
+	echo "		});\n";
+	echo "	});\n";
+	echo "</script>\n";
+
+//include the footer
+	require_once "resources/footer.php";
+
+?>

+ 64 - 0
core/email_queue/email_queue_delete.php

@@ -0,0 +1,64 @@
+<?php
+/*
+	FusionPBX
+	Version: MPL 1.1
+
+	The contents of this file are subject to the Mozilla Public License Version
+	1.1 (the "License"); you may not use this file except in compliance with
+	the License. You may obtain a copy of the License at
+	http://www.mozilla.org/MPL/
+
+	Software distributed under the License is distributed on an "AS IS" basis,
+	WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+	for the specific language governing rights and limitations under the
+	License.
+
+	The Original Code is FusionPBX
+
+	The Initial Developer of the Original Code is
+	Mark J Crane <[email protected]>
+	Portions created by the Initial Developer are Copyright (C) 2022-2023
+	the Initial Developer. All Rights Reserved.
+
+	Contributor(s):
+	Mark J Crane <[email protected]>
+*/
+
+//includes files
+	require_once dirname(__DIR__, 2) . "/resources/require.php";
+	require_once "resources/check_auth.php";
+
+//check permissions
+	if (permission_exists('email_queue_delete')) {
+		//access granted
+	}
+	else {
+		echo "access denied";
+		exit;
+	}
+
+//add multi-lingual support
+	$language = new text;
+	$text = $language->get();
+
+//delete the message
+	message::add($text['message-delete']);
+
+//delete the data
+	if (isset($_GET["id"]) && is_uuid($_GET["id"])) {
+
+		//get the id
+			$id = $_GET["id"];
+
+		//delete the data
+			$array['email_queue'][]['email_queue_uuid'] = $id;
+			$database = new database;
+			$database->delete($array);
+			unset($array);
+
+		//redirect the user
+			header('Location: email_queues.php');
+	}
+
+
+?>

+ 579 - 0
core/email_queue/email_queue_edit.php

@@ -0,0 +1,579 @@
+<?php
+/*
+	FusionPBX
+	Version: MPL 1.1
+
+	The contents of this file are subject to the Mozilla Public License Version
+	1.1 (the "License"); you may not use this file except in compliance with
+	the License. You may obtain a copy of the License at
+	http://www.mozilla.org/MPL/
+
+	Software distributed under the License is distributed on an "AS IS" basis,
+	WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+	for the specific language governing rights and limitations under the
+	License.
+
+	The Original Code is FusionPBX
+
+	The Initial Developer of the Original Code is
+	Mark J Crane <[email protected]>
+	Portions created by the Initial Developer are Copyright (C) 2022-2024
+	the Initial Developer. All Rights Reserved.
+
+	Contributor(s):
+	Mark J Crane <[email protected]>
+*/
+
+//includes files
+	require_once dirname(__DIR__, 2) . "/resources/require.php";
+	require_once "resources/check_auth.php";
+
+//check permissions
+	if (permission_exists('email_queue_add') || permission_exists('email_queue_edit')) {
+		//access granted
+	}
+	else {
+		echo "access denied";
+		exit;
+	}
+
+//add multi-lingual support
+	$language = new text;
+	$text = $language->get();
+
+//action add or update
+	if (!empty($_REQUEST["id"]) && is_uuid($_REQUEST["id"])) {
+		$action = "update";
+		$email_queue_uuid = $_REQUEST["id"];
+		$id = $_REQUEST["id"];
+	}
+	else {
+		$action = "add";
+	}
+
+//get http post variables and set them to php variables
+	if (!empty($_POST) && is_array($_POST)) {
+		$email_date = $_POST["email_date"];
+		$email_from = $_POST["email_from"];
+		$email_to = $_POST["email_to"];
+		$email_subject = $_POST["email_subject"];
+		$email_body = $_POST["email_body"];
+		$email_status = $_POST["email_status"];
+		$email_retry_count = $_POST["email_retry_count"];
+		//$email_action_before = $_POST["email_action_before"];
+		$email_action_after = $_POST["email_action_after"];
+		$email_response = $_POST["email_response"];
+	}
+
+//process the user data and save it to the database
+	if (count($_POST) > 0 && empty($_POST["persistformvar"])) {
+
+		//validate the token
+			$token = new token;
+			if (!$token->validate($_SERVER['PHP_SELF'])) {
+				message::add($text['message-invalid_token'],'negative');
+				header('Location: email_queue.php');
+				exit;
+			}
+
+		//process the http post data by submitted action
+			if (!empty($_POST['action']) && !empty($_POST['action'])) {
+
+				//prepare the array(s)
+				//send the array to the database class
+				switch ($_POST['action']) {
+					case 'copy':
+						if (permission_exists('email_queue_add')) {
+							$obj = new database;
+							$obj->copy($array);
+						}
+						break;
+					case 'delete':
+						if (permission_exists('email_queue_delete')) {
+							$obj = new database;
+							$obj->delete($array);
+						}
+						break;
+					case 'toggle':
+						if (permission_exists('email_queue_update')) {
+							$obj = new database;
+							$obj->toggle($array);
+						}
+						break;
+				}
+
+				//redirect the user
+				if (in_array($_POST['action'], array('copy', 'delete', 'toggle'))) {
+					header('Location: email_queue_edit.php?id='.$id);
+					exit;
+				}
+			}
+
+		//check for all required data
+			$msg = '';
+			//if (empty($email_date)) { $msg .= $text['message-required']." ".$text['label-email_date']."<br>\n"; }
+			//if (empty($email_from)) { $msg .= $text['message-required']." ".$text['label-email_from']."<br>\n"; }
+			//if (empty($email_to)) { $msg .= $text['message-required']." ".$text['label-email_to']."<br>\n"; }
+			//if (empty($email_subject)) { $msg .= $text['message-required']." ".$text['label-email_subject']."<br>\n"; }
+			//if (empty($email_body)) { $msg .= $text['message-required']." ".$text['label-email_body']."<br>\n"; }
+			//if (empty($email_status)) { $msg .= $text['message-required']." ".$text['label-email_status']."<br>\n"; }
+			if (!empty($msg) && empty($_POST["persistformvar"])) {
+				require_once "resources/header.php";
+				require_once "resources/persist_form_var.php";
+				echo "<div align='center'>\n";
+				echo "<table><tr><td>\n";
+				echo $msg."<br />";
+				echo "</td></tr></table>\n";
+				persistformvar($_POST);
+				echo "</div>\n";
+				require_once "resources/footer.php";
+				return;
+			}
+
+		//parse email addresses to single string csv string
+			if (isset($email_to) && substr_count($email_to, "\n") != 0) {
+				$email_to_lines = explode("\n", $email_to);
+				if (is_array($email_to_lines) && @sizeof($email_to_lines) != 0) {
+					foreach ($email_to_lines as $email_to_line) {
+						if (substr_count($email_to_line, ',') != 0) {
+							$email_to_array = explode(',', $email_to_line);
+							if (is_array($email_to_array) && @sizeof($email_to_array) != 0) {
+								foreach ($email_to_array as $email_to_address) {
+									if (valid_email(trim($email_to_address))) {
+										$email_to_addresses[] = strtolower(trim($email_to_address));
+									}
+								}
+							}
+						}
+						else {
+							if (valid_email(trim($email_to_line))) {
+								$email_to_addresses[] = strtolower(trim($email_to_line));
+							}
+						}
+					}
+				}
+			}
+			else {
+				if (isset($email_to) && substr_count($email_to, ',') != 0) {
+					$email_to_array = explode(',', $email_to);
+					if (is_array($email_to_array) && @sizeof($email_to_array) != 0) {
+						foreach ($email_to_array as $email_to_address) {
+							if (valid_email(trim($email_to_address))) {
+								$email_to_addresses[] = strtolower(trim($email_to_address));
+							}
+						}
+					}
+				}
+			}
+			if (!empty($email_to_addresses) && is_array($email_to_addresses) && @sizeof($email_to_addresses) != 0) {
+				$email_to = implode(',', $email_to_addresses);
+				unset($email_to_array, $email_to_addresses);
+			}
+
+		//add the email_queue_uuid
+			if (!is_uuid($_POST["email_queue_uuid"])) {
+				$email_queue_uuid = uuid();
+			}
+
+		//prepare the array
+			$array['email_queue'][0]['email_queue_uuid'] = $email_queue_uuid;
+			$array['email_queue'][0]['domain_uuid'] = $_SESSION['domain_uuid'];
+			$array['email_queue'][0]['email_date'] = $email_date;
+			$array['email_queue'][0]['email_from'] = $email_from;
+			$array['email_queue'][0]['email_to'] = $email_to;
+			$array['email_queue'][0]['email_subject'] = $email_subject;
+			$array['email_queue'][0]['email_body'] = $email_body;
+			$array['email_queue'][0]['email_status'] = $email_status;
+			$array['email_queue'][0]['email_retry_count'] = $email_retry_count;
+			//$array['email_queue'][0]['email_action_before'] = $email_action_before;
+			$array['email_queue'][0]['email_action_after'] = $email_action_after;
+			$array['email_queue'][0]['email_response'] = $email_response;
+
+		//save the data
+			$database = new database;
+			$database->app_name = 'email queue';
+			$database->app_uuid = '5befdf60-a242-445f-91b3-2e9ee3e0ddf7';
+			$database->save($array);
+
+		//redirect the user
+			if (isset($action)) {
+				if ($action == "add") {
+					$_SESSION["message"] = $text['message-add'];
+				}
+				if ($action == "update") {
+					$_SESSION["message"] = $text['message-update'];
+				}
+				//header('Location: email_queue.php');
+				header('Location: email_queue_edit.php?id='.urlencode($email_queue_uuid));
+				return;
+			}
+	}
+
+//pre-populate the form
+	if (!empty($_GET) && is_array($_GET) && (empty($_POST["persistformvar"]) || $_POST["persistformvar"] != "true")) {
+		$sql = "select * from v_email_queue ";
+		$sql .= "where email_queue_uuid = :email_queue_uuid ";
+		//$sql .= "and domain_uuid = :domain_uuid ";
+		//$parameters['domain_uuid'] = $_SESSION['domain_uuid'];
+		$parameters['email_queue_uuid'] = $email_queue_uuid;
+		$database = new database;
+		$row = $database->select($sql, $parameters, 'row');
+		if (is_array($row) && @sizeof($row) != 0) {
+			$email_date = $row["email_date"];
+			$email_from = $row["email_from"];
+			$email_to = $row["email_to"];
+			$email_subject = $row["email_subject"];
+			$email_body = $row["email_body"];
+			$email_status = $row["email_status"];
+			$email_retry_count = $row["email_retry_count"];
+			//$email_action_before = $row["email_action_before"];
+			$email_response = $row["email_response"];
+			$email_action_after = $row["email_action_after"];
+		}
+		unset($sql, $parameters, $row);
+	}
+
+//load editor preferences/defaults
+	$setting_size = !empty($_SESSION["editor"]["font_size"]["text"]) ? $_SESSION["editor"]["font_size"]["text"] : '12px';
+	$setting_theme = !empty($_SESSION["editor"]["theme"]["text"]) ? $_SESSION["editor"]["theme"]["text"] : 'cobalt';
+	$setting_invisibles = !empty($_SESSION["editor"]["invisibles"]["boolean"]) ? $_SESSION["editor"]["invisibles"]["boolean"] : 'false';
+	$setting_indenting = !empty($_SESSION["editor"]["indent_guides"]["boolean"]) ? $_SESSION["editor"]["indent_guides"]["boolean"] : 'false';
+	$setting_numbering = !empty($_SESSION["editor"]["line_numbers"]["boolean"]) ? $_SESSION["editor"]["line_numbers"]["boolean"] : 'true';
+
+//create token
+	$object = new token;
+	$token = $object->create($_SERVER['PHP_SELF']);
+
+//show the header
+	$document['title'] = $text['title-email_queue'];
+	require_once "resources/header.php";
+
+	echo "<script language='JavaScript' type='text/javascript'>\n";
+
+	echo "	function toggle_option(opt) {\n";
+	echo "		switch (opt) {\n";
+	echo "			case 'numbering':\n";
+	echo "				toggle_option_do('showLineNumbers');\n";
+	echo "				toggle_option_do('fadeFoldWidgets');\n";
+	echo "				break;\n";
+	echo "			case 'invisibles':\n";
+	echo "				toggle_option_do('showInvisibles');\n";
+	echo "				break;\n";
+	echo "			case 'indenting':\n";
+	echo "				toggle_option_do('displayIndentGuides');\n";
+	echo "				break;\n";
+	echo "		}\n";
+	echo "		focus_editor();\n";
+	echo "	}\n";
+
+	echo "	function toggle_option_do(opt_name) {\n";
+	echo "		var opt_val = editor.getOption(opt_name);\n";
+	echo "		editor.setOption(opt_name, ((opt_val) ? false : true));\n";
+	echo "	}\n";
+
+	echo "	function focus_editor() {\n";
+	echo "		editor.focus();\n";
+	echo "	}\n";
+
+	//copy the value from the editor on submit
+	echo "	function set_value() {\n";
+	echo "		$('#email_body').val(editor.session.getValue());\n";
+	echo "	}\n";
+
+	//load editor value from hidden textarea
+	echo "	function load_value() {\n";
+	echo "		editor.session.setValue($('#email_body').val());";
+	echo "	}\n";
+
+	echo "</script>\n";
+
+	echo "<style>\n";
+	echo "	div#editor {\n";
+	echo "		text-align: left;\n";
+	echo "		width: 100%;\n";
+	echo "		height: 300px;\n";
+	echo "		font-size: 12px;\n";
+	echo "		}\n";
+	echo "</style>\n";
+
+//show the content
+	echo "<form name='frm' id='frm' method='post' action=''>\n";
+	echo "<input class='formfld' type='hidden' name='email_queue_uuid' value='".escape($email_queue_uuid)."'>\n";
+
+	echo "<div class='action_bar' id='action_bar'>\n";
+	echo "	<div class='heading'><b>".$text['title-email_queue']."</b></div>\n";
+	echo "	<div class='actions'>\n";
+	echo button::create(['type'=>'button','label'=>$text['button-back'],'icon'=>$_SESSION['theme']['button_icon_back'],'id'=>'btn_back','collapse'=>'hide-xs','style'=>'margin-right: 15px;','link'=>'email_queue.php']);
+	if ($action == 'update') {
+		if (permission_exists('_add')) {
+			echo button::create(['type'=>'button','label'=>$text['button-copy'],'icon'=>$_SESSION['theme']['button_icon_copy'],'id'=>'btn_copy','name'=>'btn_copy','style'=>'display: none;','onclick'=>"modal_open('modal-copy','btn_copy');"]);
+		}
+		if (permission_exists('_delete')) {
+			echo button::create(['type'=>'button','label'=>$text['button-delete'],'icon'=>$_SESSION['theme']['button_icon_delete'],'id'=>'btn_delete','name'=>'btn_delete','style'=>'display: none; margin-right: 15px;','onclick'=>"modal_open('modal-delete','btn_delete');"]);
+		}
+	}
+	echo button::create(['type'=>'submit','label'=>$text['button-save'],'icon'=>$_SESSION['theme']['button_icon_save'],'id'=>'btn_save','collapse'=>'hide-xs']);
+	echo "	</div>\n";
+	echo "	<div style='clear: both;'></div>\n";
+	echo "</div>\n";
+
+	echo $text['title_description-email_queue']."\n";
+	echo "<br /><br />\n";
+
+	if ($action == 'update') {
+		if (permission_exists('email_queue_add')) {
+			echo modal::create(['id'=>'modal-copy','type'=>'copy','actions'=>button::create(['type'=>'submit','label'=>$text['button-continue'],'icon'=>'check','id'=>'btn_copy','style'=>'float: right; margin-left: 15px;','collapse'=>'never','name'=>'action','value'=>'copy','onclick'=>"modal_close();"])]);
+		}
+		if (permission_exists('email_queue_delete')) {
+			echo modal::create(['id'=>'modal-delete','type'=>'delete','actions'=>button::create(['type'=>'submit','label'=>$text['button-continue'],'icon'=>'check','id'=>'btn_delete','style'=>'float: right; margin-left: 15px;','collapse'=>'never','name'=>'action','value'=>'delete','onclick'=>"modal_close();"])]);
+		}
+	}
+
+	echo "<div class='card'>\n";
+	echo "<table width='100%' border='0' cellpadding='0' cellspacing='0'>\n";
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-email_date']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' style='position: relative;' align='left'>\n";
+	echo "  <input class='formfld' type='text' name='email_date' maxlength='255' value='".escape($email_date)."'>\n";
+	echo "<br />\n";
+	echo $text['description-email_date']."\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-email_from']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' style='position: relative;' align='left'>\n";
+	echo "	<input class='formfld' type='text' name='email_from' maxlength='255' value='".escape($email_from)."'>\n";
+	echo "<br />\n";
+	echo $text['description-email_from']."\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-email_to']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' style='position: relative;' align='left'>\n";
+	if (isset($email_to) && substr_count($email_to, ',') != 0) {
+		echo "	<textarea class='formfld' style='width: 450px; height: 100px;' name='email_to'>";
+		$email_to_array = explode(',', $email_to);
+		if (is_array($email_to_array) && @sizeof($email_to_array) != 0) {
+			foreach ($email_to_array as $email_to_address) {
+				echo escape($email_to_address)."\n";
+			}
+		}
+		echo "</textarea>\n";
+	}
+	else {
+		echo "	<input class='formfld' type='text' name='email_to' maxlength='255' value='".escape($email_to)."'>\n";
+	}
+	echo "<br />\n";
+	echo $text['description-email_to']."\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-email_subject']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' style='position: relative;' align='left'>\n";
+	echo "	<input class='formfld' type='text' name='email_subject' maxlength='255' value='".escape($email_subject)."'>\n";
+	echo "<br />\n";
+	echo $text['description-email_subject']."\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-email_body']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' style='position: relative;' align='left'>\n";
+	echo "	<textarea class='formfld' name='email_body' id='email_body' style='display: none;'>".$email_body."</textarea>\n";
+	echo "	<div id='editor'></div>\n";
+	echo "	<table cellpadding='0' cellspacing='0' border='0' style='float: right; padding-top: 5px;'>\n";
+	echo "		<tr>\n";
+	echo "			<td valign='middle' style='padding-left: 6px;'><i class='fas fa-list-ul fa-lg ace_control' title=\"".$text['label-toggle_line_numbers']."\" onclick=\"toggle_option('numbering');\"></i></td>\n";
+	echo "			<td valign='middle' style='padding-left: 6px;'><i class='fas fa-eye-slash fa-lg ace_control' title=\"".$text['label-toggle_invisibles']."\" onclick=\"toggle_option('invisibles');\"></i></td>\n";
+	echo "			<td valign='middle' style='padding-left: 6px;'><i class='fas fa-indent fa-lg ace_control' title=\"".$text['label-toggle_indent_guides']."\" onclick=\"toggle_option('indenting');\"></i></td>\n";
+	echo "			<td valign='middle' style='padding-left: 6px;'><i class='fas fa-search fa-lg ace_control' title=\"".$text['label-find_replace']."\" onclick=\"editor.execCommand('replace');\"></i></td>\n";
+	echo "			<td valign='middle' style='padding-left: 6px;'><i class='fas fa-chevron-down fa-lg ace_control' title=\"".$text['label-go_to_line']."\" onclick=\"editor.execCommand('gotoline');\"></i></td>\n";
+	echo "			<td valign='middle' style='padding-left: 15px;'>\n";
+	echo "				<select id='size' class='formfld' onchange=\"document.getElementById('editor').style.fontSize = this.options[this.selectedIndex].value; focus_editor();\">\n";
+	$sizes = explode(',','9px,10px,11px,12px,14px,16px,18px,20px');
+	if (!in_array($setting_size, $sizes)) {
+		echo "				<option value='".$setting_size."'>".escape($setting_size)."</option>\n";
+		echo "				<option value='' disabled='disabled'></option>\n";
+	}
+	foreach ($sizes as $size) {
+		$selected = $size == $setting_size ? 'selected' : null;
+		echo "				<option value='".$size."' ".$selected.">".escape($size)."</option>\n";
+	}
+	echo "				</select>\n";
+	echo "			</td>\n";
+	echo "			<td valign='middle' style='padding-left: 4px; padding-right: 0px;'>\n";
+	$themes['Light']['chrome']= 'Chrome';
+	$themes['Light']['clouds']= 'Clouds';
+	$themes['Light']['crimson_editor']= 'Crimson Editor';
+	$themes['Light']['dawn']= 'Dawn';
+	$themes['Light']['dreamweaver']= 'Dreamweaver';
+	$themes['Light']['eclipse']= 'Eclipse';
+	$themes['Light']['github']= 'GitHub';
+	$themes['Light']['iplastic']= 'IPlastic';
+	$themes['Light']['solarized_light']= 'Solarized Light';
+	$themes['Light']['textmate']= 'TextMate';
+	$themes['Light']['tomorrow']= 'Tomorrow';
+	$themes['Light']['xcode']= 'XCode';
+	$themes['Light']['kuroir']= 'Kuroir';
+	$themes['Light']['katzenmilch']= 'KatzenMilch';
+	$themes['Light']['sqlserver']= 'SQL Server';
+	$themes['Dark']['ambiance']= 'Ambiance';
+	$themes['Dark']['chaos']= 'Chaos';
+	$themes['Dark']['clouds_midnight']= 'Clouds Midnight';
+	$themes['Dark']['cobalt']= 'Cobalt';
+	$themes['Dark']['idle_fingers']= 'idle Fingers';
+	$themes['Dark']['kr_theme']= 'krTheme';
+	$themes['Dark']['merbivore']= 'Merbivore';
+	$themes['Dark']['merbivore_soft']= 'Merbivore Soft';
+	$themes['Dark']['mono_industrial']= 'Mono Industrial';
+	$themes['Dark']['monokai']= 'Monokai';
+	$themes['Dark']['pastel_on_dark']= 'Pastel on dark';
+	$themes['Dark']['solarized_dark']= 'Solarized Dark';
+	$themes['Dark']['terminal']= 'Terminal';
+	$themes['Dark']['tomorrow_night']= 'Tomorrow Night';
+	$themes['Dark']['tomorrow_night_blue']= 'Tomorrow Night Blue';
+	$themes['Dark']['tomorrow_night_bright']= 'Tomorrow Night Bright';
+	$themes['Dark']['tomorrow_night_eighties']= 'Tomorrow Night 80s';
+	$themes['Dark']['twilight']= 'Twilight';
+	$themes['Dark']['vibrant_ink']= 'Vibrant Ink';
+	echo "				<select id='theme' class='formfld' onchange=\"editor.setTheme('ace/theme/' + this.options[this.selectedIndex].value); focus_editor();\">\n";
+	foreach ($themes as $optgroup => $theme) {
+		echo "				<optgroup label='".$optgroup."'>\n";
+		foreach ($theme as $value => $label) {
+			$selected = strtolower($label) == strtolower($setting_theme) ? 'selected' : null;
+			echo "				<option value='".$value."' ".$selected.">".escape($label)."</option>\n";
+		}
+		echo "				</optgroup>\n";
+	}
+
+	echo "				</select>\n";
+	echo "			</td>\n";
+	echo "		</tr>\n";
+	echo "	</table>\n";
+	echo "<br />\n";
+	echo $text['description-email_body']."\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-email_status']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' style='position: relative;' align='left'>\n";
+	echo "	<select class='formfld' name='email_status'>\n";
+	echo "		<option value='waiting' ".($email_status == 'waiting' ? "selected='selected'" : null).">".ucwords($text['label-waiting'])."</option>\n";
+	echo "		<option value='trying' ".($email_status == 'trying' ? "selected='selected'" : null).">".ucwords($text['label-trying'])."</option>\n";
+	echo "		<option value='sent' ".($email_status == 'sent' ? "selected='selected'" : null).">".ucwords($text['label-sent'])."</option>\n";
+	echo "		<option value='failed' ".($email_status == 'failed' ? "selected='selected'" : null).">".ucwords($text['label-failed'])."</option>\n";
+	echo "	</select>\n";
+	echo "<br />\n";
+	echo $text['description-email_status']."\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-email_retry_count']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' style='position: relative;' align='left'>\n";
+	echo "	<input class='formfld' type='text' name='email_retry_count' maxlength='255' value='".escape($email_retry_count)."'>\n";
+	echo "<br />\n";
+	echo $text['description-email_retry_count']."\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	//echo "<tr>\n";
+	//echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	//echo "	".$text['label-email_action_before']."\n";
+	//echo "</td>\n";
+	//echo "<td class='vtable' style='position: relative;' align='left'>\n";
+	//echo "	<input class='formfld' type='text' name='email_action_before' maxlength='255' value='".escape($email_action_before)."'>\n";
+	//echo "<br />\n";
+	//echo $text['description-email_action_before']."\n";
+	//echo "</td>\n";
+	//echo "</tr>\n";
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-email_action_after']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' style='position: relative;' align='left'>\n";
+	echo "	<input class='formfld' type='text' name='email_action_after' maxlength='255' value='".escape($email_action_after)."'>\n";
+	echo "<br />\n";
+	echo $text['description-email_action_after']."\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	if ($_SESSION['email_queue']['save_response']['boolean'] == 'true') {
+		echo "<tr>\n";
+		echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+		echo "	".$text['label-email_response']."\n";
+		echo "</td>\n";
+		echo "<td class='vtable' style='position: relative;' align='left'>\n";
+		echo "	<textarea class='formfld' style='width: 450px; height: 100px;' name='email_response'>".$email_response."</textarea>\n";
+		echo "<br />\n";
+		echo ($text['description-email_response'] ?? '')."\n";
+		echo "</td>\n";
+		echo "</tr>\n";
+	}
+
+	echo "</table>";
+	echo "</div>";
+	echo "<br /><br />";
+
+	echo "<input type='hidden' name='".$token['name']."' value='".$token['hash']."'>\n";
+
+	echo "</form>";
+
+
+	echo "<script type='text/javascript' src='".PROJECT_PATH."/resources/ace/ace.js' charset='utf-8'></script>\n";
+	echo "<script type='text/javascript'>\n";
+
+//load editor
+	echo "	var editor = ace.edit('editor');\n";
+	echo "	editor.setOptions({\n";
+	echo "		mode: 'ace/mode/html',\n";
+	echo "		theme: 'ace/theme/'+document.getElementById('theme').options[document.getElementById('theme').selectedIndex].value,\n";
+	echo "		selectionStyle: 'text',\n";
+	echo "		cursorStyle: 'smooth',\n";
+	echo "		showInvisibles: ".$setting_invisibles.",\n";
+	echo "		displayIndentGuides: ".$setting_indenting.",\n";
+	echo "		showLineNumbers: ".$setting_numbering.",\n";
+	echo "		showGutter: true,\n";
+	echo "		scrollPastEnd: true,\n";
+	echo "		fadeFoldWidgets: ".$setting_numbering.",\n";
+	echo "		showPrintMargin: false,\n";
+	echo "		highlightGutterLine: false,\n";
+	echo "		useSoftTabs: false\n";
+	echo "		});\n";
+	echo "	document.getElementById('editor').style.fontSize='".$setting_size."';\n";
+	echo "	focus_editor();\n";
+
+//load value into editor
+	echo "	load_value();\n";
+
+//remove certain keyboard shortcuts
+	echo "	editor.commands.bindKey('Ctrl-T', null);\n"; //disable transpose letters - prefer new browser tab
+	echo "	editor.commands.bindKey('Ctrl-F', null);\n"; //disable find - control broken with bootstrap
+	echo "	editor.commands.bindKey('Ctrl-H', null);\n"; //disable replace - control broken with bootstrap
+
+	echo "</script>\n";
+
+//include the footer
+	require_once "resources/footer.php";
+
+?>

+ 127 - 0
core/email_queue/email_test.php

@@ -0,0 +1,127 @@
+<?php
+/*-
+ * Copyright (c) 2008-2023 Mark J Crane <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+//includes files
+	require_once dirname(__DIR__, 2) . "/resources/require.php";
+	require_once "resources/check_auth.php";
+
+//check permissions
+	if (!permission_exists('email_queue_view')) {
+		echo "access denied";
+		exit;
+	}
+
+//add multi-lingual support
+	$language = new text;
+	$text = $language->get();
+
+//prepare the email
+	$email_recipient = !empty($_POST['to']) && valid_email($_POST['to']) ? strtolower($_POST['to']) : null;
+
+	$email_body = "<b>Test Message</b><br /><br />\n";
+	$email_body .= "This message is a test of the SMTP settings configured within your PBX.<br />\n";
+	$email_body .= "If you received this message, your current SMTP settings are valid.<br /><br />\n";
+
+	$email_from_address = $_SESSION['email']['smtp_from']['text'];
+	$email_from_name = $_SESSION['email']['smtp_from_name']['text'];
+
+//send email
+	$sent = 0;
+	$email = new email;
+	$email->recipients = $email_recipient;
+	$email->subject = 'Test Message';
+	$email->body = $email_body;
+	$email->from_address = $email_from_address;
+	$email->from_name = $email_from_name;
+	$email->attachments = $email_attachments ?? null;
+	$email->debug_level = 3;
+	$email->method = 'direct';
+	ob_start();
+	$sent = $email->send();
+	$send_response = ob_get_contents();
+	ob_end_clean();
+	$end_response = $email->response;
+
+//format response
+	$email_response = array_merge(explode("\n", str_replace('<br>', '', $end_response)), explode("<br>\n", $send_response));
+	if (!empty($email_response) && is_array($email_response) && @sizeof($email_response) != 0) {
+		foreach ($email_response as $x => $line) {
+			if (empty(trim($line))) { unset($email_response[$x]); }
+		}
+	}
+
+//show the content
+	echo "<input type='button' class='btn' style='float: right;' value='".$text['button-close']."' onclick=\"$('#test_result_layer').fadeOut(200);\">\n";
+	echo "<b>".$text['header-email_test']."</b>\n";
+	echo "<br><br>\n";
+
+	echo $text['description-email_test']."\n";
+	echo "<br><br><br>\n";
+
+	echo "<b>".$text['header-settings']."</b>\n";
+	echo "<br><br>\n";
+	ksort($_SESSION['email']);
+	echo "<table>\n";
+	foreach ($_SESSION['email'] as $name => $setting) {
+		foreach ($setting as $type => $value) {
+			echo "<tr>\n";
+			if ($type == 'uuid') { $uuid = $value; continue; }
+			if ($name == 'smtp_password') { $value = str_repeat('*', strlen($value)); }
+			if (permission_exists('default_setting_edit')) {
+				echo "<td style='padding-right: 30px;'><a href='../../core/default_settings/default_setting_edit.php?id=".$uuid."' target='_blank'>".$name."</a></td>\n";
+				echo "<td style='padding-right: 30px;'>".$value."</td>\n";
+			}
+			else {
+				echo "<td style='padding-right: 30px;'>".$name."</td>\n";
+				echo "<td style='padding-right: 30px;'>".$value."</td>\n";
+			}
+			echo "<tr>\n";
+		}
+	}
+	echo "</table>\n";
+	echo "<br><br>\n";
+
+	echo "<b>".$text['header-connection']."</b>\n";
+	echo "<br><br>\n";
+
+	echo "<div style='width: 100%; max-height: 250px; overflow: auto; border: 1px solid ".($_SESSION['theme']['table_row_border_color']['text'] ?? '#c5d1e5')."; padding: 12px 15px; background-color: ".($_SESSION['theme']['table_row_background_color_light']['text'] ?? '#fff')."; font-family: monospace; font-size: 85%;'>\n";
+
+	if (!empty($email_response) && is_array($email_response) && @sizeof($email_response) != 0) {
+		echo implode("<br>\n<hr style='margin: 3px 0;'>\n", $email_response);
+	}
+	echo "</div>\n";
+	echo "<br><br>\n";
+
+	echo "<b>".$text['header-result']."</b>\n";
+	echo "<br><br>\n";
+	echo $sent ? "Message Sent Successfully<br>Receipient: <a href='mailto:".$email_recipient."'>".$email_recipient."</a>" : "Message Failed";
+
+	echo "<br><br>\n";
+	echo "<center>\n";
+	echo "	<input type='button' class='btn' style='margin-top: 15px;' value='".$text['button-close']."' onclick=\"$('#test_result_layer').fadeOut(200);\">\n";
+	echo "</center>\n";
+
+?>

+ 230 - 0
core/email_queue/resources/classes/email_queue.php

@@ -0,0 +1,230 @@
+<?php
+
+/**
+ * email_queue class
+ *
+ * @method null delete
+ * @method null toggle
+ * @method null copy
+ */
+if (!class_exists('email_queue')) {
+	class email_queue {
+
+		/**
+		* declare the variables
+		*/
+		private $app_name;
+		private $app_uuid;
+		private $name;
+		private $table;
+		private $toggle_field;
+		private $toggle_values;
+		private $location;
+
+		/**
+		 * called when the object is created
+		 */
+		public function __construct() {
+			//assign the variables
+				$this->app_name = 'email_queue';
+				$this->app_uuid = '5befdf60-a242-445f-91b3-2e9ee3e0ddf7';
+				$this->name = 'email_queue';
+				$this->table = 'email_queue';
+				$this->toggle_field = '';
+				$this->toggle_values = ['true','false'];
+				$this->location = 'email_queue.php';
+		}
+
+		/**
+		 * delete rows from the database
+		 */
+		public function delete($records) {
+			if (permission_exists($this->name.'_delete')) {
+
+				//add multi-lingual support
+					$language = new text;
+					$text = $language->get();
+
+				//validate the token
+					$token = new token;
+					if (!$token->validate($_SERVER['PHP_SELF'])) {
+						message::add($text['message-invalid_token'],'negative');
+						header('Location: '.$this->location);
+						exit;
+					}
+
+				//delete multiple records
+					if (is_array($records) && @sizeof($records) != 0) {
+						//build the delete array
+							$x = 0;
+							foreach ($records as $record) {
+								//add to the array
+									if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
+										$array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
+										$array['email_queue_attachments'][$x][$this->name.'_uuid'] = $record['uuid'];
+										//$array[$this->table][$x]['domain_uuid'] = $_SESSION['domain_uuid'];
+									}
+
+								//increment the id
+									$x++;
+							}
+
+						//delete the checked rows
+							if (is_array($array) && @sizeof($array) != 0) {
+								//execute delete
+									$database = new database;
+									$database->app_name = $this->app_name;
+									$database->app_uuid = $this->app_uuid;
+									$database->delete($array);
+									unset($array);
+
+								//set message
+									message::add($text['message-delete']);
+							}
+							unset($records);
+					}
+			}
+		}
+
+		/**
+		 * toggle a field between two values
+		 */
+		public function toggle($records) {
+			if (permission_exists($this->name.'_edit')) {
+
+				//add multi-lingual support
+					$language = new text;
+					$text = $language->get();
+
+				//validate the token
+					$token = new token;
+					if (!$token->validate($_SERVER['PHP_SELF'])) {
+						message::add($text['message-invalid_token'],'negative');
+						header('Location: '.$this->location);
+						exit;
+					}
+
+				//toggle the checked records
+					if (is_array($records) && @sizeof($records) != 0) {
+						//get current toggle state
+							foreach($records as $record) {
+								if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
+									$uuids[] = "'".$record['uuid']."'";
+								}
+							}
+							if (is_array($uuids) && @sizeof($uuids) != 0) {
+								$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
+								$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
+								$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
+								$parameters['domain_uuid'] = $_SESSION['domain_uuid'];
+								$database = new database;
+								$rows = $database->select($sql, $parameters, 'all');
+								if (is_array($rows) && @sizeof($rows) != 0) {
+									foreach ($rows as $row) {
+										$states[$row['uuid']] = $row['toggle'];
+									}
+								}
+								unset($sql, $parameters, $rows, $row);
+							}
+
+						//build update array
+							$x = 0;
+							foreach($states as $uuid => $state) {
+								//create the array
+									$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
+									$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
+
+								//increment the id
+									$x++;
+							}
+
+						//save the changes
+							if (is_array($array) && @sizeof($array) != 0) {
+								//save the array
+									$database = new database;
+									$database->app_name = $this->app_name;
+									$database->app_uuid = $this->app_uuid;
+									$database->save($array);
+									unset($array);
+
+								//set message
+									message::add($text['message-toggle']);
+							}
+							unset($records, $states);
+					}
+			}
+		}
+
+		/**
+		 * copy rows from the database
+		 */
+		public function copy($records) {
+			if (permission_exists($this->name.'_add')) {
+
+				//add multi-lingual support
+					$language = new text;
+					$text = $language->get();
+
+				//validate the token
+					$token = new token;
+					if (!$token->validate($_SERVER['PHP_SELF'])) {
+						message::add($text['message-invalid_token'],'negative');
+						header('Location: '.$this->location);
+						exit;
+					}
+
+				//copy the checked records
+					if (is_array($records) && @sizeof($records) != 0) {
+
+						//get checked records
+							foreach($records as $record) {
+								if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
+									$uuids[] = "'".$record['uuid']."'";
+								}
+							}
+
+						//create the array from existing data
+							if (is_array($uuids) && @sizeof($uuids) != 0) {
+								$sql = "select * from v_".$this->table." ";
+								$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
+								$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
+								$parameters['domain_uuid'] = $_SESSION['domain_uuid'];
+								$database = new database;
+								$rows = $database->select($sql, $parameters, 'all');
+								if (is_array($rows) && @sizeof($rows) != 0) {
+									$x = 0;
+									foreach ($rows as $row) {
+										//copy data
+											$array[$this->table][$x] = $row;
+
+										//add copy to the description
+											$array[$this->table][$x][$this->name.'_uuid'] = uuid();
+
+										//increment the id
+											$x++;
+									}
+								}
+								unset($sql, $parameters, $rows, $row);
+							}
+
+						//save the changes and set the message
+							if (is_array($array) && @sizeof($array) != 0) {
+								//save the array
+									$database = new database;
+									$database->app_name = $this->app_name;
+									$database->app_uuid = $this->app_uuid;
+									$database->save($array);
+									unset($array);
+
+								//set message
+									message::add($text['message-copy']);
+							}
+							unset($records);
+					}
+			}
+		}
+
+	}
+}
+
+?>

+ 260 - 0
core/email_queue/resources/command/send.php

@@ -0,0 +1,260 @@
+<?php
+/*
+	Copyright (c) 2023 Mark J Crane <[email protected]>
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions
+	are met:
+
+		1. Redistributions of source code must retain the above copyright
+		notice, this list of conditions and the following disclaimer.
+
+		2. Redistributions in binary form must reproduce the above copyright
+		notice, this list of conditions and the following disclaimer in the
+		documentation and/or other materials provided with the distribution.
+
+	THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+	ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+	ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+	FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+	DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+	OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+	LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+	OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+	SUCH DAMAGE.
+*/
+
+//check the permission
+	if (defined('STDIN')) {
+		//includes files
+		require_once dirname(__DIR__, 4) . "/resources/require.php";
+	}
+	else {
+		exit;
+	}
+
+//increase limits
+	set_time_limit(0);
+	//ini_set('max_execution_time',1800); //30 minutes
+	ini_set('memory_limit', '512M');
+
+//save the arguments to variables
+	$script_name = $argv[0];
+	if (!empty($argv[1])) {
+		parse_str($argv[1], $_GET);
+	}
+
+//define the short options
+	// : required, :: optional, no colon no value
+	//$short_options  = "a"; // email address
+	//$short_options .= "l:"; // template language
+	//$short_options .= "c:"; // template_category
+	//$short_options .= "s:"; // template_subcategory
+	//$short_options .= "t::"; // template_type
+	//$short_options .= "D::"; // domain
+
+//define the long options
+	$long_options = array(
+		"email_address:",
+		"email_attachment::",
+		"template_language:",
+		"template_category:",
+		"template_subcategory:",
+		"template_type:",
+		"domain_name:",
+		"debug:"
+	);
+
+//get the email attachment allowed paths
+	if (isset($conf['email.attachments.0.path'])) {
+		$i = 0;
+		while(true) {
+			if (isset($conf['email.attachments.'.$i.'.path'])) {
+				$attachment_allowed_paths[] = $conf['email.attachments.'.$i.'.path'];
+			}
+			else {
+				break;
+			}
+			$i++;
+		}
+	}
+
+//get the command line parameters
+	$options = getopt(null, $long_options);
+
+//set the values from the command line parameters
+	foreach($options as $option_key => $option_value) {
+		switch ($option_key) {
+			case 'email_address':
+				if (is_array($option_value)) {
+					$email_array = $option_value;
+				}
+				else {
+					$email_array[] = $option_value;
+				}
+				break;
+			case 'email_attachment':
+				if (is_array($option_value)) {
+					$email_attachment_array = $option_value;
+				}
+				else {
+					$email_attachment_array[] = $option_value;
+				}
+				break;
+			case 'template_language':
+				$template_language = $option_value;
+				break;
+			case 'template_category':
+				$template_category = $option_value;
+				break;
+			case 'template_subcategory':
+				$template_subcategory = $option_value;
+				break;
+			case 'template_type':
+				$template_type = $option_value;
+				break;
+			case 'domain_name':
+				$domain_name = $option_value;
+				break;
+			case 'debug':
+				$debug = $option_value;
+				break;
+		}
+	}
+
+//set default values
+	if (empty($template_language)) {
+		$template_language = 'en-us';
+	}
+	if (empty($template_type)) {
+		$template_type = 'html';
+	}
+
+//prepare the email attachment
+	$i = 0;
+	foreach($email_attachment_array as $email_attachment) {
+		foreach($attachment_allowed_paths as $allowed_path) {
+			if ($allowed_path == dirname($email_attachment) && file_exists($email_attachment)) {
+				$email_attachments[$i]['path'] = dirname($email_attachment);
+				$email_attachments[$i]['name'] = basename($email_attachment);
+			}
+			$i++;
+		}
+	}
+
+//get the domain_uuid
+	$sql = "select domain_uuid from v_domains ";
+	$sql .= "where domain_name = :domain_name ";
+	$parameters['domain_name'] = $domain_name;
+	$database = new database;
+	$domain_uuid = $database->select($sql, $parameters, 'column');
+	unset($parameters);
+
+//get the email queue settings
+	$setting = new settings(["domain_uuid" => $domain_uuid]);
+	$smtp_from = $setting->get('email', 'smtp_from');
+	$smtp_from_name = $setting->get('email', 'smtp_from_name', $smtp_from);
+	$save_response = $setting->get('email_queue', 'save_response');
+
+//debug information
+	if (!empty($debug) && $debug == 'true') {
+		echo "email_address: "; print_r($email_array);
+		echo "template_language: ".$template_language."\n";
+		echo "template_category: ".$template_category."\n";
+		echo "template_subcategory: ".$template_subcategory."\n";
+		echo "template_type: ".$template_type."\n";
+		echo "domain_name: ".$domain_name."\n";
+		echo "debug: ".$debug."\n";
+		echo "smtp_from: $smtp_from\n";
+		echo "smtp_from_name: $smtp_from_name\n";
+	}
+
+//define the message variable
+	$message = '';
+
+//show required details
+	if (empty($smtp_from)) {
+		$message .= "smtp_from needs to be set in Default Settings\n";
+	}
+	if (!is_array($email_array)) {
+		$message .= "email_address\n";
+	}
+	if (empty($smtp_from)) {
+		$message .= "template_category\n";
+	}
+	if (empty($template_subcategory)) {
+		$message .= "template_subcategory\n";
+	}
+	if (empty($template_subcategory)) {
+		$message .= "template_subcategory\n";
+	}
+	if (empty($domain_name)) {
+		$message .= "domain_name\n";
+	}
+	if (!empty($message)) {
+		echo "Following parameters are required\n";
+		echo $message;
+		exit;
+	}
+
+//get the email template from the database
+	$sql = "select template_subject, template_body from v_email_templates ";
+	$sql .= "where template_enabled = 'true' ";
+	$sql .= "and template_language = :template_language ";
+	$sql .= "and template_category = :template_category ";
+	$sql .= "and template_subcategory = :template_subcategory ";
+	$sql .= "and template_type = :template_type ";
+	$sql .= "and (domain_uuid = :domain_uuid or domain_uuid is null) ";
+	$parameters['domain_uuid'] = $domain_uuid;
+	$parameters['template_language'] = $template_language;
+	$parameters['template_category'] = $template_category;
+	$parameters['template_subcategory'] = $template_subcategory;
+	$parameters['template_type'] = $template_type;
+	$database = new database;
+	$row = $database->select($sql, $parameters, 'row');
+	if (is_array($row)) {
+		$email_subject = $row['template_subject'];
+		$email_body = $row['template_body'];
+	}
+	unset($sql, $parameters);
+
+//replace variables in email subject
+	if (!empty($email_subject)) {
+		$email_subject = str_replace('${domain_name}', $domain_name, $email_subject);
+	}
+
+//replace variables in email body
+	if (!empty($email_body)) {
+		$email_body = str_replace('${domain_name}', $domain_name, $email_body);
+	}
+
+//more debug information
+	if (!empty($debug) && $debug == 'true') {
+		echo "email_subject: $email_subject\n";
+		echo "email_body: ";
+		echo $email_body."\n";
+	}
+
+//create the email object
+	$email = new email;
+
+//send email
+	foreach ($email_array as $email_address) {
+		$email->recipients = $email_address;
+		$email->subject = $email_subject;
+		$email->body = $email_body;
+		$email->from_address = $smtp_from;
+		$email->from_name = $smtp_from_name;
+		if (isset($email_attachments)) {
+			$email->attachments = $email_attachments;
+		}
+		$email->debug_level = 3;
+		$email_response = $email->send();
+		if (!empty($debug) && $debug == 'true') {
+			echo $email_response;
+		}
+	}
+
+?>

+ 400 - 0
core/email_queue/resources/functions/transcribe.php

@@ -0,0 +1,400 @@
+<?php
+
+if (!function_exists('transcribe')) {
+	function transcribe ($file_path, $file_name, $file_extension) {
+		//check if the file exists
+			if (!file_exists($file_path.'/'.$file_name)) {
+				echo "file not found ".$file_path.'/'.$file_name;
+				exit;
+			}
+
+		//get the email queue settings
+			$setting = new settings(['category' => 'voicemail']);
+
+		//transcription variables
+			$transcribe_provider = $setting->get('voicemail', 'transcribe_provider');
+			$transcribe_language = $setting->get('voicemail', 'transcribe_language');
+
+		//transcribe - watson
+			if ($transcribe_provider == 'watson') {
+				$api_key = $setting->get('voicemail', 'watson_key');
+				$api_url = $setting->get('voicemail', 'watson_url');
+
+				if ($file_extension == "mp3") {
+					$content_type = 'audio/mp3';
+				}
+				if ($file_extension == "wav") {
+					$content_type = 'audio/wav';
+				}
+
+				if (isset($api_key) && $api_key != '') {
+					//start output buffer
+					ob_start();  
+					$out = fopen('php://output', 'w');
+
+					//create the curl resource
+					$ch = curl_init();
+
+					//set the curl options
+					curl_setopt($ch, CURLOPT_URL, $api_url);
+					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+					curl_setopt($ch, CURLOPT_USERPWD, 'apikey' . ':' . $api_key);
+					curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); //set the authentication type
+					curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: '.$content_type]);
+					curl_setopt($ch, CURLOPT_BINARYTRANSFER,TRUE);
+					curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents($file_path.'/'.$file_name));
+					curl_setopt($ch, CURLOPT_POST, 1);
+					curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);	//The number of seconds to wait while trying to connect.
+					curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);	//To follow any "Location: " header that the server sends as part of the HTTP header.
+					curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);	//To automatically set the Referer: field in requests where it follows a Location: redirect.
+					curl_setopt($ch, CURLOPT_TIMEOUT, 300);	//The maximum number of seconds to allow cURL functions to execute.
+					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);	//To stop cURL from verifying the peer's certificate.
+					curl_setopt($ch, CURLOPT_HEADER, 0); //hide the headers when set to 0
+
+					//add verbose for debugging
+					curl_setopt($ch, CURLOPT_VERBOSE, true);
+					curl_setopt($ch, CURLOPT_STDERR, $out);
+
+					//execute the curl with the options
+					$http_content = curl_exec($ch);
+
+					//return the error
+					if (curl_errno($ch)) {
+						echo 'Error:' . curl_error($ch);
+					}
+
+					//close the curl resource
+					curl_close($ch);
+
+					//show the debug information
+					fclose($out);
+					$debug = ob_get_clean();
+					echo $debug;
+
+					//$command = "curl -X POST -silent -u \"apikey:".$api_key."\" --header \"Content-type: ".$content_type."\" --data-binary @".$file_path."/".$file_name." \"".$api_url."\"";
+					//echo "command: ".$command."\n";
+
+					//ob_start();
+					//$result = passthru($command);
+					//$json_result = ob_get_contents();
+					//ob_end_clean();
+
+					//run the command
+					//$http_response = shell_exec($command);
+					//echo "http_response:\n".$http_response."\n";
+
+					//remove headers and return the http content
+					//$http_response = trim(str_ireplace("HTTP/1.1 100 Continue", "", $http_response));
+
+					//$temp_array = explode("HTTP/1.1 200 OK", $http_response);
+					//$http_array = explode("\r\n\r\n", $temp_array[1]);
+					//$http_content = trim($http_array[1]);
+					echo "http_content:\n".$http_content."\n";
+
+					//validate the json
+					$ob = json_decode($http_content);
+					if($ob === null) {
+						echo "invalid json\n";
+						return false;
+					}
+
+					$message = '';
+					$json = json_decode($http_content, true);
+					//echo "json; ".$json."\n";
+					foreach($json['results'] as $row) {
+						$message .= $row['alternatives'][0]['transcript'];
+					}
+
+					$message = str_replace("%HESITATION", " ", trim($message));
+					$message = ucfirst($message);
+					$array['provider'] = $transcribe_provider;
+					$array['language'] = $transcribe_language;
+					//$array['command'] = $command;
+					$array['message'] = $message;
+
+					return $array;
+				}
+			}
+
+		//transcribe - google
+			if ($transcribe_provider == 'google') {
+				$api_key = $setting->get('voicemail', 'google_key');
+				$api_url = $setting->get('voicemail', 'google_url');
+				$application_credentials = $setting->get('voicemail', 'google_application_credentials');
+				$transcribe_language =  $setting->get('voicemail', 'transcribe_language');
+				$transcribe_alternate_language = $setting->get('voicemail', 'transcribe_alternate_language');
+
+				if (!isset($transcribe_language) && empty($transcribe_language)) {
+					$transcribe_language = 'en-US';
+				}
+				if (!isset($transcribe_alternate_language) && empty($transcribe_alternate_language)) {
+					$transcribe_alternate_language = 'es-US';
+				}
+				if ($file_extension == "mp3") {
+					$content_type = 'audio/mp3';
+				}
+				if ($file_extension == "wav") {
+					$content_type = 'audio/wav';
+				}
+				
+				//version 1
+				if (substr($api_url, 0, 32) == 'https://speech.googleapis.com/v1') {
+					if (isset($api_key) && $api_key != '') {
+						$command = "sox ".$file_path."/".$file_name." ".$file_path."/".$file_name.".flac trim 0 00:59 ";
+						$command .= "&& echo \"{ 'config': { 'languageCode': '".$transcribe_language."', 'enableWordTimeOffsets': false , 'enableAutomaticPunctuation': true , 'alternativeLanguageCodes': '".$transcribe_alternate_language."' }, 'audio': { 'content': '`base64 -w 0 ".$file_path."/".$file_name.".flac`' } }\" ";
+						$command .= "| curl -X POST -H \"Content-Type: application/json\" -d @- ".$api_url.":recognize?key=".$api_key." ";
+						$command .= "&& rm -f ".$file_path."/".$file_name.".flac";
+						echo $command."\n";
+					}
+				}
+				//version 2
+				elseif (substr($api_url, 0, 32) == 'https://speech.googleapis.com/v2') {
+					if (!empty(($application_credentials))) {
+						putenv("GOOGLE_APPLICATION_CREDENTIALS=".$application_credentials);
+					}
+					$command = "echo \"{ 'config': { 'auto_decoding_config': {}, 'language_codes': ['".$transcribe_language."'], 'model': 'long' }, 'content': '`base64 -w 0 ".$file_path."/".$file_name."`' } \" ";
+					$command .= "| curl -X POST -H \"Content-Type: application/json\" -H \"Authorization: Bearer \$(gcloud auth application-default print-access-token)\" -d @- ".$api_url;
+					echo $command."\n";
+				}
+
+				//ob_start();
+				//$result = passthru($command);
+				//$json_result = ob_get_contents();
+				//ob_end_clean();
+
+				//run the command
+				if (!empty($command)) {
+					$http_response = shell_exec($command);
+				}
+
+				//validate the json
+				if (!empty($http_response)) {
+					$ob = json_decode($http_response);
+					if($ob === null) {
+						echo "invalid json\n";
+						return false;
+					}
+
+					$json = json_decode($http_response, true);
+					//echo "json; ".$json."\n";
+					$message = '';
+					foreach($json['results'] as $row) {
+						$message .= $row['alternatives'][0]['transcript'];
+					}
+				}
+
+				//build the response
+				$array['provider'] = $transcribe_provider;
+				$array['language'] = $transcribe_language;
+				$array['command'] = $command ?? '';
+				$array['message'] = $message ?? '';
+				//print_r($array);
+
+				return $array;
+			}
+
+		//transcribe - azure
+			if ($transcribe_provider == 'azure') {
+				$api_key = $setting->get('voicemail', 'azure_key');
+				$api_url = $setting->get('voicemail', 'azure_server_region');
+
+				if (empty($transcribe_language)) {
+					$transcribe_language = 'en-US';
+				}
+
+				if ($file_extension == "mp3") {
+					$content_type = 'audio/mp3';
+				}
+				if ($file_extension == "wav") {
+					$content_type = 'audio/wav';
+				}
+
+				if (isset($api_key) && $api_key != '') {
+					$command = "curl -X POST \"https://".$api_url.".api.cognitive.microsoft.com/sts/v1.0/issueToken\" -H \"Content-type: application/x-www-form-urlencoded\" -H \"Content-Length: 0\" -H \"Ocp-Apim-Subscription-Key: ".$api_key."\"";
+					$access_token_result = shell_exec($command);
+					if (empty($access_token_result)) {
+						return false;
+					}
+					else {
+						$file_path = $file_path.'/'.$file_name;
+						$command = "curl -X POST \"https://".$api_url.".stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=".$transcribe_language."&format=detailed\" -H 'Authorization: Bearer ".$access_token_result."' -H 'Content-type: audio/wav; codec=\"audio/pcm\"; samplerate=8000; trustsourcerate=false' --data-binary @".$file_path;
+						echo $command."\n";
+						$http_response = shell_exec($command);
+						$array = json_decode($http_response, true);
+						if ($array === null) {
+							return false;
+						}
+						else {
+							$message = $array['NBest'][0]['Display'];
+						}
+					}
+					$array['provider'] = $transcribe_provider;
+					$array['language'] = $transcribe_language;
+					$array['api_key'] = $api_key;
+					$array['command'] = $command;
+					$array['message'] = $message;
+					return $array;
+				}
+
+			}
+
+			// transcribe - custom
+			// Works with self-hostable transcription service at https://github.com/AccelerateNetworks/an-transcriptions
+			if ($transcribe_provider == 'custom') {
+				$api_key = $setting->get('voicemail', 'api_key');
+				$api_url = $setting->get('voicemail', 'transcription_server');
+
+				if (empty($transcribe_language)) {
+					$transcribe_language = 'en-US';
+				}
+
+				if ($file_extension == "mp3") {
+					$content_type = 'audio/mp3';
+				}
+				if ($file_extension == "wav") {
+					$content_type = 'audio/wav';
+				}
+
+				$message = null;
+				for($retries = 5; $retries > 0; $retries--) {
+					echo "sending voicemail recording to ".$api_url." for transcription";
+
+					// submit the file for transcribing
+					$file_path = $file_path.'/'.$file_name;
+					$command = "curl -sX POST ".$api_url."/enqueue -H 'Authorization: Bearer ".$api_key."' -F file=@".$file_path;
+					$stdout = shell_exec($command);
+					$resp = json_decode($stdout, true);
+					if ($resp === null) {
+						echo "unexpected error: ".$stdout;
+						// json not parsable, try again
+						continue;
+					}
+
+					$transcription_id = $resp['id'];
+
+					// wait for transcription to complete
+					sleep(1);
+
+					while(true) {
+						echo "checking ".$api_url." for completion of job ".$transcription_id;
+						$command = "curl -s ".$api_url."/j/".$transcription_id." -H 'Authorization: Bearer ".$api_key."'";
+						$resp = json_decode(shell_exec($command), true);
+						if ($resp === null) {
+							// json not parsable, try again
+							continue;
+						}
+
+						if($resp['status'] == "failed") {
+							echo "transcription failed, retrying";
+							break;
+						}
+
+						if($resp['status'] == "finished") {
+							echo "transcription succeeded";
+							$message = $resp['result'];
+							break;
+						}
+
+						// transcription is queued or in progress, check again in 1 second
+						sleep(1);
+					}
+
+					if($message !== null) {
+						break;
+					}
+				}
+
+				if($message == null) {
+					return false;
+				}
+
+				$array['provider'] = $transcribe_provider;
+				$array['language'] = $transcribe_language;
+				$array['api_key'] = $api_key;
+				// $array['command'] = $command
+				$array['message'] = $message;
+				return $array;
+			}
+
+		//transcribe - openai
+		// settings:
+		//		openai_key (required)
+		//		openai_url
+		//		openai_model
+			if ($transcribe_provider == 'openai') {
+				$api_key = $setting->get('voicemail', 'openai_key');
+				$api_url = $setting->get('voicemail', 'openai_url');
+				$api_voice_model = $setting->get('voicemail', 'openai_model');
+
+				if (empty($api_url)) {
+					$api_url = "https://api.openai.com/v1/audio/transcriptions";
+				}
+
+				if (empty($api_voice_model)) {
+					$api_voice_model = "whisper-1";
+				}
+
+				if (isset($api_key) && $api_key != '') {
+
+					$full_file_name = $file_path.'/'.$file_name ;
+
+					//start output buffer
+					ob_start();  
+					$out = fopen('php://output', 'w');
+
+					//create the curl resource
+					$ch = curl_init();
+
+					$post_data = array(
+						'model'=>$api_voice_model,
+						'file'=>curl_file_create($full_file_name)
+					);
+
+					//set the curl options
+					curl_setopt_array($ch, array(
+						CURLOPT_URL =>$api_url,
+						CURLOPT_RETURNTRANSFER => true,
+						CURLOPT_SSL_VERIFYPEER => TRUE,
+						CURLOPT_HTTPHEADER => array('Authorization: Bearer '.$api_key),
+						CURLOPT_POSTFIELDS => $post_data,
+
+					));
+
+					// //add verbose for debugging
+					// curl_setopt($ch, CURLOPT_VERBOSE, true);
+					curl_setopt($ch, CURLOPT_STDERR, $out);
+
+					//execute the curl with the options
+					$http_content = curl_exec($ch);
+									
+					//return the error
+					if (curl_errno($ch)) {
+						echo 'Error:' . curl_error($ch);
+					}
+
+					//close the curl resource
+					curl_close($ch);
+
+					//show the debug information
+					fclose($out);
+					$debug = ob_get_clean();
+					echo $debug;
+
+					
+					$ob = json_decode($http_content, true);
+					
+					$message = $ob['text'];
+					return array(
+						'provider' => $transcribe_provider,
+						'message' => $message
+					);
+				}
+
+			}
+		// todo: add error checking
+		//		return array('message' => "Missing valid transcribe_provider";
+
+	}
+}
+	
+?>

+ 193 - 0
core/email_queue/resources/jobs/email_queue.php

@@ -0,0 +1,193 @@
+<?php
+
+//check the permission
+	if (defined('STDIN')) {
+		//includes files
+		require_once dirname(__DIR__, 4) . "/resources/require.php";
+	}
+	else {
+		exit;
+	}
+
+//includes files
+	require_once "resources/pdo.php";
+	include "resources/classes/permissions.php";
+	require $_SERVER['DOCUMENT_ROOT']."/app/email_queue/resources/functions/transcribe.php";
+
+//increase limits
+	set_time_limit(0);
+	ini_set('max_execution_time', 0);
+	ini_set('memory_limit', '512M');
+
+//save the arguments to variables
+	$script_name = $argv[0];
+	if (!empty($argv[1])) {
+		parse_str($argv[1], $_GET);
+	}
+	//print_r($_GET);
+
+//set the variables
+	if (isset($_GET['hostname'])) {
+		$hostname = urldecode($_GET['hostname']);
+	}
+	if (isset($_GET['debug'])) {
+		$debug = $_GET['debug'];
+	}
+
+//define the process id file
+	$pid_file = "/var/run/fusionpbx/".basename( $argv[0], ".php") .".pid";
+	//echo "pid_file: ".$pid_file."\n";
+
+//function to check if the process exists
+	function process_exists($file = false) {
+
+		//set the default exists to false
+		$exists = false;
+
+		//check to see if the process is running
+		if (file_exists($file)) {
+			$pid = file_get_contents($file);
+			if (posix_getsid($pid) === false) { 
+				//process is not running
+				$exists = false;
+			}
+			else {
+				//process is running
+				$exists = true;
+			}
+		}
+
+		//return the result
+		return $exists;
+	}
+
+//check to see if the process exists
+	$pid_exists = process_exists($pid_file);
+
+//prevent the process running more than once
+	if ($pid_exists) {
+		echo "Cannot lock pid file {$pid_file}\n";
+		exit;
+	}
+
+//get the email queue settings
+	$setting = new settings(["category" => "email_queue"]);
+
+//email queue enabled
+	if ($setting->get('email_queue', 'enabled') != 'true') {
+		echo "Email Queue is disabled in Default Settings\n";
+		exit;
+	}
+
+//make sure the /var/run/fusionpbx directory exists
+    if (!file_exists('/var/run/fusionpbx')) {
+        $result = mkdir('/var/run/fusionpbx', 0777, true);
+        if (!$result) {
+            die('Failed to create /var/run/fusionpbx');
+        }
+    }
+
+//create the process id file if the process doesn't exist
+	if (!$pid_exists) {
+		//remove the old pid file
+		if (file_exists($file)) {
+			unlink($pid_file);
+		}
+
+		//show the details to the user
+		//echo "The process id is ".getmypid()."\n";
+		//echo "pid_file: ".$pid_file."\n";
+
+		//save the pid file
+		file_put_contents($pid_file, getmypid());
+	}
+
+//get the call center settings
+	$interval = $setting->get('email_queue', 'interval');
+
+//set the defaults
+	if (!is_numeric($interval)) { $interval = 30; }
+
+//set the email queue limit
+	if (!empty($setting->get('email_queue', 'limit'))) {
+		$email_queue_limit = $setting->get('email_queue', 'limit');
+	}
+	else {
+		$email_queue_limit = '30';
+	}
+	if (!empty($setting->get('email_queue', 'debug'))) {
+		$debug = $setting->get('email_queue', 'debug');
+	}
+
+//get the messages waiting in the email queue
+    $sql = "select * from v_email_queue ";
+    $sql .= "where (email_status = 'waiting' or email_status = 'trying') ";
+    $sql .= "and hostname = :hostname ";
+    $sql .= "order by domain_uuid asc ";
+    $sql .= "limit :limit ";
+    if (isset($hostname)) {
+        $parameters['hostname'] = $hostname;
+    }
+    else {
+        $parameters['hostname'] = gethostname();
+    }
+    $parameters['limit'] = $email_queue_limit;
+    $database = new database;
+    $email_queue = $database->select($sql, $parameters, 'all');
+    unset($parameters);
+
+    //process the messages
+    if (is_array($email_queue) && @sizeof($email_queue) != 0) {
+	$which_php = exec('which php');
+        foreach($email_queue as $row) {
+            $command = $which_php." ".$_SERVER['DOCUMENT_ROOT']."/app/email_queue/resources/jobs/email_send.php ";
+            $command .= "'action=send&email_queue_uuid=".$row["email_queue_uuid"]."&hostname=".$hostname."'";
+            if (isset($debug)) {
+                //run process inline to see debug info
+                echo $command."\n";
+                $result = system($command);
+                echo $result."\n";
+            }
+            else {
+                //starts process rapidly doesn't wait for previous process to finish (used for production)
+                $handle = popen($command." > /dev/null &", 'r'); 
+                echo "'$handle'; " . gettype($handle) . "\n";
+                $read = fread($handle, 2096);
+                echo $read;
+                pclose($handle);
+            }
+        }
+    }
+
+//remove the old pid file
+	if (file_exists($pid_file)) {
+		unlink($pid_file);
+	}
+
+//save output to
+	//$fp = fopen(sys_get_temp_dir()."/mailer-app.log", "a");
+
+//prepare the output buffers
+	//ob_end_clean();
+	//ob_start();
+
+//message divider for log file
+	//echo "\n\n=============================================================================================================================================\n\n";
+
+//get and save the output from the buffer
+	//$content = ob_get_contents(); //get the output from the buffer
+	//$content = str_replace("<br />", "", $content);
+
+	//ob_end_clean(); //clean the buffer
+
+	//fwrite($fp, $content);
+	//fclose($fp);
+
+//notes
+	//echo __line__."\n";
+	// if not keeping the email then need to delete it after the voicemail is emailed
+
+//how to use this feature
+	// cd /var/www/fusionpbx; /usr/bin/php /var/www/fusionpbx/app/email_queue/resources/send.php
+
+?>

+ 574 - 0
core/email_queue/resources/jobs/email_send.php

@@ -0,0 +1,574 @@
+<?php
+
+//check the permission
+	if (defined('STDIN')) {
+		//includes files
+		require_once dirname(__DIR__, 4) . "/resources/require.php";
+	}
+	else {
+		exit;
+	}
+
+//include files
+	include "resources/classes/permissions.php";
+
+//increase limits
+	set_time_limit(0);
+	//ini_set('max_execution_time',1800); //30 minutes
+	ini_set('memory_limit', '512M');
+
+//save the arguments to variables
+	$script_name = $argv[0];
+	if (!empty($argv[1])) {
+		parse_str($argv[1], $_GET);
+	}
+	//print_r($_GET);
+
+//get the primary key
+	if (is_uuid($_GET['email_queue_uuid'])) {
+		$email_queue_uuid = $_GET['email_queue_uuid'];
+		$hostname = urldecode($_GET['hostname']);
+		$debug = $_GET['debug'] ?? null;
+		$sleep_seconds = $_GET['sleep'] ?? null;
+	}
+	else {
+		//invalid uuid
+		exit;
+	}
+
+//define the process id file
+	$pid_file = "/var/run/fusionpbx/email_send".".".$email_queue_uuid.".pid";
+	//echo "pid_file: ".$pid_file."\n";
+
+//function to check if the process exists
+	function process_exists($file = false) {
+
+		//set the default exists to false
+		$exists = false;
+
+		//check to see if the process is running
+		if (file_exists($file)) {
+			$pid = file_get_contents($file);
+			if (posix_getsid($pid) === false) {
+				//process is not running
+				$exists = false;
+			}
+			else {
+				//process is running
+				$exists = true;
+			}
+		}
+
+		//return the result
+		return $exists;
+	}
+
+//check to see if the process exists
+	$pid_exists = process_exists($pid_file);
+
+//prevent the process running more than once
+	if ($pid_exists) {
+		//echo "Cannot lock pid file {$pid_file}\n";
+		exit;
+	}
+
+//make sure the /var/run/fusionpbx directory exists
+	if (!file_exists('/var/run/fusionpbx')) {
+		$result = mkdir('/var/run/fusionpbx', 0777, true);
+		if (!$result) {
+			die('Failed to create /var/run/fusionpbx');
+		}
+	}
+
+//create the process id file if the process doesn't exist
+	if (!$pid_exists) {
+		//remove the old pid file
+		if (!empty($pid_file) && file_exists($pid_file)) {
+			unlink($pid_file);
+		}
+
+		//show the details to the user
+		//echo "The process id is ".getmypid()."\n";
+		//echo "pid_file: ".$pid_file."\n";
+
+		//save the pid file
+		file_put_contents($pid_file, getmypid());
+	}
+
+//sleep used for debugging
+	if (isset($sleep_seconds)) {
+		sleep($sleep_seconds);
+	}
+
+//define a function to remove html tags
+	if (!function_exists('remove_tags')) {
+		function remove_tags($string) {
+			//remove HTML tags
+			$string = preg_replace ('/<[^>]*>/', ' ', $string);
+
+			//remove control characters
+			$string = str_replace("\r", '', $string);    // --- replace with empty space
+			$string = str_replace("\n", ' ', $string);   // --- replace with space
+			$string = str_replace("\t", ' ', $string);   // --- replace with space
+
+			//remove multiple spaces
+			$string = trim(preg_replace('/ {2,}/', ' ', $string));
+			return $string;
+		}
+	}
+
+//includes
+	include_once "resources/phpmailer/class.phpmailer.php";
+	include_once "resources/phpmailer/class.smtp.php";
+
+//get the email details to send
+	$sql = "select * from v_email_queue ";
+	$sql .= "where email_queue_uuid = :email_queue_uuid ";
+	$parameters['email_queue_uuid'] = $email_queue_uuid;
+	$database = new database();
+	$row = $database->select($sql, $parameters, 'row');
+	if (is_array($row)) {
+		$domain_uuid = $row["domain_uuid"];
+		$email_date = $row["email_date"];
+		$email_from = $row["email_from"];
+		$email_to = $row["email_to"];
+		$email_subject = $row["email_subject"];
+		$email_body = $row["email_body"];
+		$email_transcription = $row["email_transcription"];
+		$email_status = $row["email_status"];
+		$email_retry_count = $row["email_retry_count"];
+		$email_uuid = $row["email_uuid"];
+		//$email_action_before = $row["email_action_before"];
+		$email_action_after = $row["email_action_after"];
+	}
+	unset($parameters);
+
+//get the email queue settings
+	$settings = new settings(["database" => $database,"domain_uuid" => $domain_uuid]);
+
+//get the email settings
+	$retry_limit = $settings->get('email_queue', 'retry_limit');
+	$transcribe_enabled = $settings->get('transcribe', 'enabled', false);
+	$save_response = $settings->get('email_queue', 'save_response');
+
+//set defaults
+	if (empty($email_retry_count)) {
+		$email_retry_count = 0;
+	}
+
+//get the voicemail details
+	$sql = "select * from v_voicemails ";
+	$sql .= "where voicemail_uuid in ( ";
+	$sql .= "	select voicemail_uuid from v_voicemail_messages	";
+	$sql .= "	where voicemail_message_uuid = :voicemail_message_uuid ";
+	$sql .= ") ";
+	$parameters['voicemail_message_uuid'] = $email_uuid;
+	$row = $database->select($sql, $parameters, 'row');
+	if (is_array($row)) {
+		//$domain_uuid = $row["domain_uuid"];
+		//$voicemail_uuid = $row["voicemail_uuid"];
+		$voicemail_id = $row["voicemail_id"];
+		//$voicemail_password = $row["voicemail_password"];
+		//$greeting_id = $row["greeting_id"];
+		//$voicemail_alternate_greet_id = $row["voicemail_alternate_greet_id"];
+		//$voicemail_mail_to = $row["voicemail_mail_to"];
+		//$voicemail_sms_to  = $row["voicemail_sms_to "];
+		$voicemail_transcription_enabled = $row["voicemail_transcription_enabled"];
+		//$voicemail_attach_file = $row["voicemail_attach_file"];
+		//$voicemail_file = $row["voicemail_file"];
+		//$voicemail_local_after_email = $row["voicemail_local_after_email"];
+		//$voicemail_enabled = $row["voicemail_enabled"];
+		//$voicemail_description = $row["voicemail_description"];
+		//$voicemail_name_base64 = $row["voicemail_name_base64"];
+		//$voicemail_tutorial = $row["voicemail_tutorial"];
+		if (gettype($voicemail_transcription_enabled) === 'string') {
+			$voicemail_transcription_enabled = ($voicemail_transcription_enabled === 'true') ? true : false;
+		}
+	}
+	unset($parameters);
+
+//get the attachments and add to the email
+	$sql = "select * from v_email_queue_attachments ";
+	$sql .= "where email_queue_uuid = :email_queue_uuid ";
+	$parameters['email_queue_uuid'] = $email_queue_uuid;
+	$email_queue_attachments = $database->select($sql, $parameters, 'all');
+	if (is_array($email_queue_attachments) && @sizeof($email_queue_attachments) != 0) {
+		foreach($email_queue_attachments as $i => $field) {
+
+			$email_queue_attachment_uuid = $field['email_queue_attachment_uuid'];
+			$domain_uuid = $field['domain_uuid'];
+			$email_attachment_type = $field['email_attachment_type'];
+			$email_attachment_path = $field['email_attachment_path'];
+			$email_attachment_name = $field['email_attachment_name'];
+			$email_attachment_mime_type = $field['email_attachment_mime_type'];
+
+			if (empty($email_attachment_mime_type)) {
+				switch ($email_attachment_type) {
+					case "wav":
+						$email_attachment_mime_type = "audio/x-wav";
+						break;
+					case "mp3":
+						$email_attachment_mime_type = "audio/x-mp3";
+						break;
+					case "pdf":
+						$email_attachment_mime_type = "application/pdf";
+						break;
+					case "tif":
+					case "tiff":
+						$email_attachment_mime_type = "image/tiff";
+						break;
+					default:
+						$email_attachment_mime_type = "binary/octet-stream";
+						break;
+				}
+			}
+
+			if ($transcribe_enabled && isset($voicemail_transcription_enabled) && $voicemail_transcription_enabled) {
+				//debug message
+				echo "transcribe enabled: true\n";
+
+				//if email transcription has a value no need to transcribe again so run the transcription when the value is empty
+				if (empty($email_transcription)) {
+					//add the settings object
+					$transcribe_engine = $settings->get('transcribe', 'engine', '');
+
+					//add the transcribe object and get the languages arrays
+					if (!empty($transcribe_engine) && class_exists('transcribe_' . $transcribe_engine)) {
+						$transcribe = new transcribe($settings);
+
+						//transcribe the voicemail recording
+						$transcribe->audio_path = $email_attachment_path;
+						$transcribe->audio_filename = $email_attachment_name;
+						$transcribe->audio_mime_type = $email_attachment_mime_type;
+						$transcribe->audio_string = (!empty($field['email_attachment_base64'])) ? base64_decode($field['email_attachment_base64']) : '';
+						$transcribe_message = $transcribe->transcribe();
+					}
+				}
+				else {
+					$transcribe_message = $email_transcription;
+				}
+
+				echo "transcribe message: ".$transcribe_message."\n";
+
+				//prepare the email body
+				$email_body = str_replace('${message_text}', $transcribe_message, $email_body);
+			}
+			else {
+				//prepare the email body
+				$email_body = str_replace('${message_text}', '', $email_body);
+			}
+
+			//base64 encode the file
+			//$file_contents = base64_encode(file_get_contents($email_attachment_path.'/'.$email_attachment_name));
+
+			//add an attachment
+			//public addAttachment ( string $path, string $name = '', string $encoding = 'base64', string $type = '', string $disposition = 'attachment' ) : boolean
+			//$mail->AddAttachment($email_attachment_path.'/'.$email_attachment_name, $email_attachment_name, 'base64', 'attachment');
+
+			//add email attachments as a string for the send_email function
+			//$email_attachments[0]['type'] = 'string';
+			//$email_attachments[0]['name'] = $email_attachment_path.'/'.$email_attachment_name;
+			//$email_attachments[0]['value'] = base64_encode(file_get_contents($email_attachment_path.'/'.$email_attachment_name));
+
+			//add email attachment as a file for the send_email function
+			$email_attachments[$i]['cid'] = $field['email_attachment_cid'];
+			$email_attachments[$i]['mime_type'] = $email_attachment_mime_type;
+			$email_attachments[$i]['name'] = $email_attachment_name;
+			$email_attachments[$i]['path'] = $email_attachment_path;
+			$email_attachments[$i]['base64'] = $field['email_attachment_base64'];
+		}
+	}
+	unset($parameters);
+
+//send context to the temp log
+	echo "Subject: ".$email_subject."\n";
+	echo "From: ".$email_from."\n";
+	echo "Reply-to: ".$email_from."\n";
+	echo "To: ".$email_to."\n";
+	echo "Date: ".$email_date."\n";
+	//echo "Transcript: ".$array['message']."\n";
+	//echo "Body: ".$email_body."\n";
+
+//update the message transcription
+	if (isset($voicemail_transcription_enabled) && $voicemail_transcription_enabled == 'true' && isset($transcribe_message)) {
+		$sql = "update v_voicemail_messages ";
+		$sql .= "set message_transcription = :message_transcription ";
+		$sql .= "where voicemail_message_uuid = :voicemail_message_uuid; ";
+		$parameters['voicemail_message_uuid'] = $email_uuid;
+		$parameters['message_transcription'] = $transcribe_message;
+		//echo $sql."\n";
+		//print_r($parameters);
+		$database->execute($sql, $parameters);
+		unset($parameters);
+	}
+
+//add email settings
+	$email_settings = '';
+	$email_setting_array = $settings->get('email');
+	ksort($email_setting_array);
+	foreach ($email_setting_array as $name => $value) {
+		if ($name == 'smtp_password') { $value = '[REDACTED]'; }
+		if (is_array($value)) {
+			foreach($value as $sub_value) {
+				$email_settings .= $name.': '.$sub_value."\n";
+			}
+		}
+		else {
+			$email_settings .= $name.': '.$value."\n";
+		}
+	}
+
+//parse email and name
+	if (!empty($email_from)) {
+		if (valid_email($email_from)) {
+			$email_from_address = $email_from;
+		}
+		else {
+			$lt_pos = strpos($email_from, '<');
+			if ($lt_pos !== false) {
+				$email_from_address = str_replace('>', '', substr($email_from, $lt_pos + 1));
+				$email_from_name = trim(substr($email_from, 0, $lt_pos));
+			}
+		}
+	}
+
+//send the email
+	$email = new email;
+	$email->domain_uuid = $domain_uuid;
+	$email->from_address = $email_from_address;
+	if (!empty($email_from_name)) {
+		$email->from_name = $email_from_name;
+	}
+	$email->recipients = $email_to;
+	$email->subject = $email_subject;
+	$email->body = $email_body;
+	$email->attachments = $email_attachments;
+	$email->debug_level = 3;
+	$email->method = 'direct';
+	$email_status = $email->send();
+	$email_error = $email->error;
+	$email_response = $email->response;
+
+//send the email
+	if ($email_status) {
+
+		//set the email status to sent
+		$sql = "update v_email_queue ";
+		$sql .= "set email_status = 'sent', ";
+		if (isset($transcribe_message)) {
+			$sql .= "email_body = :email_body, ";
+			$sql .= "email_transcription = :email_transcription, ";
+			$parameters['email_body'] = $email_body;
+			$parameters['email_transcription'] = $transcribe_message;
+		}
+		if (isset($save_response) && $save_response == 'true') {
+			$sql .= "email_response = :email_response, ";
+			$parameters['email_response'] = $email_settings."\n".$email_response;
+		}
+		$sql .= "update_date = now() ";
+		$sql .= "where email_queue_uuid = :email_queue_uuid; ";
+		$parameters['email_queue_uuid'] = $email_queue_uuid;
+		$database->execute($sql, $parameters);
+		unset($parameters);
+
+		//delete the email after it is sent
+		if ($email_action_after == 'delete') {
+			//delay the delete by a few seconds
+			sleep(3);
+
+			//remove the email file after it has been sent
+			if (is_array($email_queue_attachments) && @sizeof($email_queue_attachments) != 0) {
+				foreach ($email_queue_attachments as $field) {
+					$email_attachment_path = $field['email_attachment_path'];
+					$email_attachment_name = $field['email_attachment_name'];
+					$email_attachment_name_no_prefix = str_replace(['msg_','intro_'], '', pathinfo($email_attachment_name, PATHINFO_BASENAME));
+					@unlink($email_attachment_path.'/'.$email_attachment_name);
+					@unlink($email_attachment_path.'/intro_'.$email_attachment_name_no_prefix);
+					@unlink($email_attachment_path.'/msg_'.$email_attachment_name_no_prefix);
+					@unlink($email_attachment_path.'/intro_msg_'.$email_attachment_name_no_prefix);
+				}
+			}
+
+			//delete the voicemail message from the database
+			$sql = "delete from v_voicemail_messages ";
+			$sql .= "where voicemail_message_uuid = :voicemail_message_uuid; ";
+			$parameters['voicemail_message_uuid'] = $email_uuid;
+			//echo $sql."\n";
+			//print_r($parameters);
+			$database->execute($sql, $parameters);
+			unset($parameters);
+
+			//get the domain_name
+			$sql = "select domain_name from v_domains ";
+			$sql .= "where domain_uuid = :domain_uuid ";
+			$parameters['domain_uuid'] = $domain_uuid;
+			$domain_name = $database->select($sql, $parameters, 'column');
+
+			//send the message waiting status
+			$esl = event_socket::create();
+			if ($esl->is_connected()) {
+				//$switch_cmd .= "luarun app.lua voicemail mwi ".$voicemail_id."@".$domain_name;
+				$switch_cmd .= "luarun app/voicemail/resources/scripts/mwi_notify.lua $voicemail_id $domain_name 0 0";
+				$switch_result = event_socket::api($switch_cmd);
+				echo $switch_cmd."\n";
+			}
+			else {
+				echo "event socket connection failed\n";
+			}
+		}
+
+		if ($settings->get('voicemail', 'storage_type') == 'base64') {
+			//delay the delete by a few seconds
+			sleep(3);
+
+			//remove message files after email sent
+			if (is_array($email_queue_attachments) && @sizeof($email_queue_attachments) != 0) {
+				foreach ($email_queue_attachments as $field) {
+					$email_attachment_path = $field['email_attachment_path'];
+					$email_attachment_name = $field['email_attachment_name'];
+					$email_attachment_name_no_prefix = str_replace(['msg_','intro_'], '', pathinfo($email_attachment_name, PATHINFO_BASENAME));
+					@unlink($email_attachment_path.'/'.$email_attachment_name);
+					@unlink($email_attachment_path.'/intro_'.$email_attachment_name_no_prefix);
+					@unlink($email_attachment_path.'/msg_'.$email_attachment_name_no_prefix);
+					@unlink($email_attachment_path.'/intro_msg_'.$email_attachment_name_no_prefix);
+				}
+			}
+		}
+
+
+		/*
+		//build insert array
+			$array['email_queue'][0]['email_queue_uuid'] = $email_queue_uuid;
+			//$array['email_queue'][0]['sent_date'] = 'now()';
+			$array['email_queue'][0]['email_status'] = 'sent';
+
+		//grant temporary permissions
+			$p = new permissions;
+			$p->add('email_queue_add', 'temp');
+			$p->add('email_queue_update', 'temp');
+		//execute insert
+			$database->app_name = 'email_queue';
+			$database->app_uuid = '5befdf60-a242-445f-91b3-2e9ee3e0ddf7';
+			print_r($array);
+			$message = $database->save($array);
+			print_r($message);
+			unset($array);
+		//revoke temporary permissions
+			$p->delete('email_queue_add', 'temp');
+			$p->delete('email_queue_update', 'temp');
+		*/
+
+		//send a message to the console
+			echo "Message sent!\n";
+
+	}
+	else {
+
+		$mailer_error = $mail->ErrorInfo;
+		echo "Mailer Error: ".$mailer_error."\n\n";
+
+		/*
+		//build insert array
+		$email_log_uuid = uuid();
+		$array['email_queue'][0]['email_queue_uuid'] = $email_queue_uuid;
+		$array['email_queue'][0]['email_status'] = 'failed';
+
+		//grant temporary permissions
+		$p = new permissions;
+		$p->add('email_queue_add', 'temp');
+
+		//execute insert
+		$database->app_name = 'email_queue';
+		$database->app_uuid = 'ba41954e-9d21-4b10-bbc2-fa5ceabeb184';
+		$database->save($array);
+		unset($array);
+
+		//revoke temporary permissions
+		$p->delete('email_queue_add', 'temp');
+		*/
+
+		//set the email retry count
+		$email_retry_count++;
+
+		//set the email status to failed
+		$sql = "update v_email_queue ";
+		if ($email_retry_count >= $retry_limit) {
+			$sql .= "set email_status = 'failed', ";
+		}
+		else {
+			$sql .= "set email_status = 'trying', ";
+		}
+		$sql .= "email_response = :email_response, ";
+		$sql .= "email_retry_count = :email_retry_count, ";
+		$sql .= "update_date = now() ";
+		$sql .= "where email_queue_uuid = :email_queue_uuid; ";
+		$parameters['email_queue_uuid'] = $email_queue_uuid;
+		$parameters['email_response'] = $email_settings."\n".$email_response;
+		$parameters['email_retry_count'] = $email_retry_count;
+		$database->execute($sql, $parameters);
+		unset($parameters);
+
+		/*
+		$call_uuid = $headers["X-FusionPBX-Call-UUID"];
+		if ($resend == true) {
+			echo "Retained in v_email_logs \n";
+		}
+		else {
+			// log/store message in database for review
+			if (!isset($email_log_uuid)) {
+				//build insert array
+					$email_log_uuid = uuid();
+					$array['email_logs'][0]['email_log_uuid'] = $email_log_uuid;
+					if (is_uuid($call_uuid)) {
+						$array['email_logs'][0]['call_uuid'] = $call_uuid;
+					}
+					$array['email_logs'][0]['domain_uuid'] = $headers["X-FusionPBX-Domain-UUID"];
+					$array['email_logs'][0]['sent_date'] = 'now()';
+					$array['email_logs'][0]['type'] = $headers["X-FusionPBX-Email-Type"];
+					$array['email_logs'][0]['status'] = 'failed';
+					$array['email_logs'][0]['email'] = str_replace("'", "''", $msg);
+				//grant temporary permissions
+					$p = new permissions;
+					$p->add('email_log_add', 'temp');
+				//execute insert
+					$database->app_name = 'v_mailto';
+					$database->app_uuid = 'ba41954e-9d21-4b10-bbc2-fa5ceabeb184';
+					$database->save($array);
+					unset($array);
+				//revoke temporary permissions
+					$p->delete('email_log_add', 'temp');
+			}
+
+			echo "Retained in v_email_logs as email_log_uuid = ".$email_log_uuid."\n";
+		}
+		*/
+
+	}
+
+//remove the old pid file
+	if (file_exists($pid_file)) {
+		unlink($pid_file);
+	}
+
+//unset the php mail object
+	unset($mail);
+
+//save output to
+	//$esl = fopen(sys_get_temp_dir()."/mailer-app.log", "a");
+
+//prepare the output buffers
+	//ob_end_clean();
+	//ob_start();
+
+//message divider for log file
+	//echo "\n\n====================================================\n\n";
+
+//get and save the output from the buffer
+	//$content = ob_get_contents(); //get the output from the buffer
+	//$content = str_replace("<br />", "", $content);
+
+	//ob_end_clean(); //clean the buffer
+
+	//fwrite($esl, $content);
+	//fclose($esl);
+

+ 32 - 0
core/email_queue/resources/service/debian.service

@@ -0,0 +1,32 @@
+; Author: Mark J Crane <[email protected]>
+; cp /var/www/fusionpbx/app/email_queue/resources/service/debian.service /etc/systemd/system/email_queue.service
+; systemctl enable email_queue
+; systemctl start email_queue
+; systemctl daemon-reload
+
+[Unit]
+Description=FusionPBX Email Queue
+Wants=network-online.target
+Requires=network.target local-fs.target
+;Requires=network.target local-fs.target postgresql.service
+After=network.target network-online.target local-fs.target
+;After=network.target network-online.target local-fs.target postgresql.service
+StartLimitIntervalSec=0
+
+[Service]
+Type=simple
+;Type=forking
+PIDFile=/var/run/fusionpbx/email_queue.pid
+WorkingDirectory=/var/www/fusionpbx
+;Environment="USER=www-data"
+;Environment="GROUP=www-data"
+;EnvironmentFile=-/etc/default/fusionpbx
+ExecStartPre=/bin/mkdir -p /var/run/fusionpbx
+;ExecStartPre=/bin/chown -R ${USER}:${GROUP} /var/www/fusionpbx
+ExecStart=/usr/bin/php /var/www/fusionpbx/app/email_queue/resources/service/email_queue.php
+TimeoutSec=55s
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+Also=

+ 209 - 0
core/email_queue/resources/service/email_queue.php

@@ -0,0 +1,209 @@
+<?php
+
+//add the document root to the include path
+	if (defined('STDIN')) {
+		//includes files
+		require_once dirname(__DIR__, 4) . "/resources/require.php";
+	}
+	else {
+		exit;
+	}
+
+//include files
+	include "resources/classes/permissions.php";
+
+//increase limits
+	set_time_limit(0);
+	ini_set('max_execution_time', 0);
+	ini_set('memory_limit', '512M');
+
+//save the arguments to variables
+	$script_name = $argv[0];
+	if (!empty($argv[1])) {
+		parse_str($argv[1], $_GET);
+	}
+	//print_r($_GET);
+
+//set the variables
+	if (isset($_GET['hostname'])) {
+		$hostname = urldecode($_GET['hostname']);
+	}
+	if (isset($_GET['debug'])) {
+		$debug = $_GET['debug'];
+	}
+
+//get the hostname
+	if (!isset($hostname)) {
+		$hostname = gethostname();
+	}
+
+//define the process id file
+	$pid_file = "/var/run/fusionpbx/".basename( $argv[0], ".php") .".pid";
+	//echo "pid_file: ".$pid_file."\n";
+
+//function to check if the process exists
+	function process_exists($file = false) {
+
+		//set the default exists to false
+		$exists = false;
+
+		//check to see if the process is running
+		if (file_exists($file)) {
+			$pid = file_get_contents($file);
+			if (function_exists('posix_getsid')) {
+				if (posix_getsid($pid) === false) { 
+					//process is not running
+					$exists = false;
+				}
+				else {
+					//process is running
+					$exists = true;
+				}
+			}
+			else {
+				if (file_exists('/proc/'.$pid)) {
+					//process is running
+					$exists = true;
+				}
+				else {
+					//process is not running
+					$exists = false;
+				}
+			}
+		}
+
+		//return the result
+		return $exists;
+	}
+
+//check to see if the process exists
+	$pid_exists = process_exists($pid_file);
+
+//prevent the process running more than once
+	if ($pid_exists) {
+		echo "Cannot lock pid file {$pid_file}\n";
+		exit;
+	}
+
+//get the email queue settings
+	$setting = new settings(["category" => "email_queue"]);
+
+//email queue enabled
+	if ($setting->get('email_queue', 'enabled') != 'true') {
+		echo "Email Queue is disabled in Default Settings\n";
+		exit;
+	}
+
+//make sure the /var/run/fusionpbx directory exists
+    if (!file_exists('/var/run/fusionpbx')) {
+        $result = mkdir('/var/run/fusionpbx', 0777, true);
+        if (!$result) {
+            die('Failed to create /var/run/fusionpbx');
+        }
+    }
+
+//create the process id file if the process doesn't exist
+	if (!$pid_exists) {
+		//remove the old pid file
+		if (file_exists($pid_file)) {
+			unlink($pid_file);
+		}
+
+		//show the details to the user
+		//echo "The process id is ".getmypid()."\n";
+		//echo "pid_file: ".$pid_file."\n";
+
+		//save the pid file
+		file_put_contents($pid_file, getmypid());
+	}
+
+//get the call center settings
+	$interval = $setting->get('email_queue', 'interval');
+
+//set the defaults
+	if (!is_numeric($interval)) { $interval = 30; }
+
+//set the email queue limit
+	if (!empty($setting->get('email_queue', 'limit'))) {
+		$email_queue_limit = $setting->get('email_queue', 'limit');
+	}
+	else {
+		$email_queue_limit = '30';
+	}
+	if (!empty($setting->get('email_queue', 'debug'))) {
+		$debug = $setting->get('email_queue', 'debug');
+	}
+
+//get the messages waiting in the email queue
+	while (true) {
+
+		//get the messages that are waiting to send
+		$sql = "select * from v_email_queue ";
+		$sql .= "where (email_status = 'waiting' or email_status = 'trying') ";
+		$sql .= "and hostname = :hostname ";
+		$sql .= "order by domain_uuid asc ";
+		$sql .= "limit :limit ";
+		$parameters['hostname'] = $hostname;
+		$parameters['limit'] = $email_queue_limit;
+		$database = new database;
+		$email_queue = $database->select($sql, $parameters, 'all');
+		unset($parameters);
+
+		//process the messages
+		if (is_array($email_queue) && @sizeof($email_queue) != 0) {
+			foreach($email_queue as $row) {
+				$command = exec('which php')." ".$_SERVER['DOCUMENT_ROOT']."/app/email_queue/resources/jobs/email_send.php ";
+				$command .= "'action=send&email_queue_uuid=".$row["email_queue_uuid"]."&hostname=".$hostname."'";
+				if (isset($debug)) {
+					//run process inline to see debug info
+					echo $command."\n";
+					$result = system($command);
+					echo $result."\n";
+				}
+				else {
+					//starts process rapidly doesn't wait for previous process to finish (used for production)
+					$handle = popen($command." > /dev/null &", 'r'); 
+					echo "'$handle'; " . gettype($handle) . "\n";
+					$read = fread($handle, 2096);
+					echo $read;
+					pclose($handle);
+				}
+			}
+		}
+
+		//pause to prevent excessive database queries
+		sleep($interval);
+	}
+
+//remove the old pid file
+	if (file_exists($pid_file)) {
+		unlink($pid_file);
+	}
+
+//save output to
+	//$fp = fopen(sys_get_temp_dir()."/mailer-app.log", "a");
+
+//prepare the output buffers
+	//ob_end_clean();
+	//ob_start();
+
+//message divider for log file
+	//echo "\n\n=============================================================================================================================================\n\n";
+
+//get and save the output from the buffer
+	//$content = ob_get_contents(); //get the output from the buffer
+	//$content = str_replace("<br />", "", $content);
+
+	//ob_end_clean(); //clean the buffer
+
+	//fwrite($fp, $content);
+	//fclose($fp);
+
+//notes
+	//echo __line__."\n";
+	// if not keeping the email then need to delete it after the voicemail is emailed
+
+//how to use this feature
+	// cd /var/www/fusionpbx; /usr/bin/php /var/www/fusionpbx/app/email_queue/resources/send.php
+
+?>