From d691538dcb9122bd0ea059b46b597e801af922a2 Mon Sep 17 00:00:00 2001 From: Steve Sutton Date: Thu, 30 May 2019 16:30:23 -0400 Subject: [PATCH] DB updates and queueing the email messages. Search now queues the messages into the email_queue table. Starting working on the cron task. --- classes/data/dataEmailMessages.php | 14 ++ defines.php | 4 + index.php | 2 +- models/admin/messages/index.php | 214 +++++++++++++++++- setup/adminHooks.php | 21 ++ ..._V0.0.1.sql => create_database_V0.0.2.sql} | 6 +- setup/databaseScripts/dbVersions.php | 1 + .../update_database_V0.0.2.sql | 27 +++ views/admin/messages/list.html | 4 +- views/admin/messages/search.html | 5 +- 10 files changed, 288 insertions(+), 10 deletions(-) rename setup/databaseScripts/{create_database_V0.0.1.sql => create_database_V0.0.2.sql} (90%) create mode 100644 setup/databaseScripts/update_database_V0.0.2.sql diff --git a/classes/data/dataEmailMessages.php b/classes/data/dataEmailMessages.php index 3e629b5..f56c241 100644 --- a/classes/data/dataEmailMessages.php +++ b/classes/data/dataEmailMessages.php @@ -73,6 +73,8 @@ class GlmDataEmailMessages extends GlmDataAbstract */ public $fields = false; + public $postStats = false; + /** * Constructor * @@ -182,6 +184,18 @@ class GlmDataEmailMessages extends GlmDataAbstract */ public function entryPostProcessing($r, $a) { + if ( $this->postStats ) { + // get number of queued emails for this message. + $queued = $this->wpdb->get_var( + $this->wpdb->prepare( + "SELECT count(*) + FROM " . GLM_MEMBERS_MESSAGES_PLUGIN_DB_PREFIX . "email_queue + WHERE message_id = %d", + $r['id'] + ) + ); + $r['stats'] = $queued; + } return $r; } diff --git a/defines.php b/defines.php index 1caf121..9dbe077 100644 --- a/defines.php +++ b/defines.php @@ -22,6 +22,10 @@ global $wpdb; define('GLM_MEMBERS_MESSAGES_PLUGIN_DB_PREFIX', $wpdb->prefix.'glm_membersMessages_'); define('GLM_MEMBERS_MESSAGES_PLUGIN_ACTIVE_DB_OPTION', 'glmMembersMessagesDbVersion'); +// These two defines are used to make sure the queue is processed only once. +define( 'GLM_MEMBERS_MESSAGES_QUEUE_LOCK', 'glmMembersMessageLock' ); +define( 'GLM_MEMBERS_MESSAGES_QUEUE_LOCK_TIMEOUT', '30' ); + // Determine which system we're running on - If not provided, assume PRODUCTION $host = getenv('GLM_HOST_ID'); if (trim($host) == '') { diff --git a/index.php b/index.php index 513cfe1..be26c59 100644 --- a/index.php +++ b/index.php @@ -44,7 +44,7 @@ if (!defined('ABSPATH')) { * version from this plugin. */ define('GLM_MEMBERS_MESSAGES_PLUGIN_VERSION', '0.0.1'); -define('GLM_MEMBERS_MESSAGES_PLUGIN_DB_VERSION', '0.0.1'); +define('GLM_MEMBERS_MESSAGES_PLUGIN_DB_VERSION', '0.0.2'); // This is the minimum version of the GLM Members DB plugin require for this plugin. define('GLM_MEMBERS_MESSAGES_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION', '2.8.0'); diff --git a/models/admin/messages/index.php b/models/admin/messages/index.php index f356d7e..deaad4f 100644 --- a/models/admin/messages/index.php +++ b/models/admin/messages/index.php @@ -120,9 +120,10 @@ class GlmMembersAdmin_messages_index extends GlmDataEmailMessages case 'search': $view = 'search'; $searchResults = array(); + $messages = array(); $mTypeSelected = false; $whereParts = array( - "T.status != " . $this->config['status_numb']['Archived'] + "T.status != " . $this->config['status_numb']['Archived'] ); wp_enqueue_style( 'select2','https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css' ); @@ -188,7 +189,7 @@ class GlmMembersAdmin_messages_index extends GlmDataEmailMessages // Get a list of member_types for filtering require_once GLM_MEMBERS_PLUGIN_CLASS_PATH . '/data/dataMemberTypes.php'; - $MemberTypes = new GlmDataMemberTypes( $this->wpdb, $this->config ); + $MemberTypes = new GlmDataMemberTypes( $this->wpdb, $this->config ); $member_types = $MemberTypes->getList(); // Check if there is a member_type filter @@ -205,11 +206,19 @@ class GlmMembersAdmin_messages_index extends GlmDataEmailMessages $where = implode( ' AND ', $whereParts ); // echo '
$where: ' . print_r( $where, true ) . '
'; - $searchResults = $Members->getList( $where ); + $searchResults = $Members->getSimpleMemberInfoList( $where ); + // echo '
$searchResults: ' . print_r( $searchResults, true ) . '
'; + + $messages = $this->getList(); + + if ( $option2 === 'sendMessages' && isset( $_REQUEST['message_id'] ) && $messageId = filter_var( $_REQUEST['message_id'], FILTER_VALIDATE_INT ) ) { + $this->sendHtmlMessages( $searchResults, $messageId ); + } } $tData = array( + 'messages' => $messages, 'mTypeSelected' => $mTypeSelected, 'categories' => $categories, 'member_types' => $member_types, @@ -219,7 +228,9 @@ class GlmMembersAdmin_messages_index extends GlmDataEmailMessages case 'list': $view = 'list'; + $this->postStats = true; $messages = $this->getList(); + $this->postStats = false; $tData = array( 'messages' => $messages, ); @@ -266,5 +277,202 @@ class GlmMembersAdmin_messages_index extends GlmDataEmailMessages } + /** + * sendHtmlMessages + * + * Bulid the html email message for the each member and send it out. + * + * @param $data Member data from search + * @param $message Message array + */ + public function sendHtmlMessages( $data, $messageId ) + { + // echo '
$messageId: ' . print_r( $messageId, true ) . '
'; + // echo '
$data: ' . print_r( $data, true ) . '
'; + $message = $this->getEntry( $messageId ); + // echo '
$message: ' . print_r( $message, true ) . '
'; + $fromEmail = $message['from_email']; + $fromName = $message['from_name']; + $replyToEmail = $message['reply_to_email']; + $subject = $message['subject']; + + if ( $messageId && $message && is_array( $data ) && !empty( $data ) ) { + foreach ( $data as $memData ) { + // echo '
$memData: ' . print_r( $memData, true ) . '
'; + // get member contact data + require_once GLM_MEMBERS_CONTACTS_PLUGIN_CLASS_PATH . '/data/dataContacts.php'; + $Contacts = new GlmDataContacts( $this->wpdb, $this->config ); + $whereParts = array(); + $whereParts[] = "T.ref_dest = " . $memData['member_pointer']; + $whereParts[] = "T.active = true"; + $whereParts[] = "T.email like '%@%'"; + $where = implode( " AND ", $whereParts ); + $memberContacts = $Contacts->getSimplified( $where ); + // echo '
$memberContacts: ' . print_r( $memberContacts, true ) . '
'; + if ( $memberContacts && !empty( $memberContacts ) ) { + foreach ( $memberContacts as $contact ) { + $emailData = array( + 'member' => array( + 'name' => $memData['member'], + ), + 'contact' => array( + 'fname' => $contact['fname'], + 'lname' => $contact['lname'], + ) + ); + $messageBody = $this->generateHTML( $emailData, $message['message_body'], true ); + + // Add this to the email_queue + $this->wpdb->insert( + GLM_MEMBERS_MESSAGES_PLUGIN_DB_PREFIX . 'email_queue', + array( + 'message_id' => $messageId, + 'to_email' => $contact['email'], + 'subject' => $subject, + 'from_email' => $fromEmail, + 'reply_to_email' => $replyToEmail, + 'message_body' => $messageBody, + 'queue_date' => date( 'Y-m-d H:i:s' ), + 'processed' => false, + ), + array( + '%d', // message_id + '%s', // to_email + '%s', // subject + '%s', // from_email + '%s', // reply_to_email + '%s', // message_body + '%s', // queue_date + '%s', // processed + ) + ); + } + } + } + } + } + + /** + * Merge template and data to produce HTML + * + * Checks the theme's view directories and the view directories for + * this plugin for a matching view file. + * + * Note that $view needs to have the proper view directory path + * includes. (i.e. "/views/front/registrations/summary.html") + * + * $view may also be a template as a string if $viewIsString is true. + * + * @param $data array Array of data to merge with the template + * @param $view string Name of view file (see above)) + * @param $viewIsString boolean If true, $view is a string containing the view. + * + * @access public + * @return void + */ + function generateHTML( $data, $view, $viewIsString = false ) + { + + // Load Smarty Template support + $smarty = new smartyTemplateSupport(); + + // Add standard parameters + require GLM_MEMBERS_PLUGIN_SETUP_PATH . '/standardTemplateParams.php'; + + // Add data from model to Smarty template + if ( is_array( $data ) && count( $data ) > 0 ) { + foreach ( $data as $k => $d ) { + $smarty->templateAssign( $k, $d ); + } + } + + + // If is supplied as a string + if ( $viewIsString ) { + + $out = $smarty->template->fetch( 'eval:' . $view ); + + // Otherwise $view is a file name + } else { + + // Get the specified view file - check theme first + $viewPath = GLM_MEMBERS_PLUGIN_CURRENT_THEME_DIR . '/views'; + $viewPath2 = GLM_MEMBERS_WORDPRESS_PLUGIN_PATH . 'views'; // Save default + + // If the view is not found in the theme, fall back to views in the plugin + if ( !is_file( $viewPath . '/' . $view ) ) { + + // Next try the plugin/add-on + $viewPath = GLM_MEMBERS_REGISTRATIONS_PLUGIN_PATH . "/views"; + + if ( !is_file( $viewPath . '/' . $view ) ) { + + if ( GLM_MEMBERS_PLUGIN_FRONT_DEBUG ) { + trigger_error( "Bad or missing view file when generating checkout HTML: $viewPath/$view", E_USER_NOTICE ); + } + + } + + } + + // Update the Smarty view path + $smarty->template->setTemplateDir( $viewPath ); + + // If the view path doesn't match the default, add the default (using theme view) + if ( $viewPath2 != $viewPath ) { + $smarty->template->addTemplateDir( $viewPath2 ); + } + + // Generate output from model data and view + $out = $smarty->template->fetch( $view ); + + } + + return $out; + + } + + /** + * sendHtmlEmail + * + * Create html email and send using wp_mail. + * + * @param mixed $to To email address + * @param mixed $subject Subject line for the email + * @param mixed $htmlMessage Html message for the email + * + * @access public + * @return void + */ + public function sendHtmlEmail( $from, $to, $subject, $htmlMessage ) + { + + // Set the From name using this wordpress hook. + add_filter( + 'wp_mail_from_name', + function ( $name ) { + return $this->config['settings']['reg_org_name']; + } + ); + // Send confirmation email, set the content type to allow html by using this filter + add_filter( 'wp_mail_content_type', array( $this, 'set_content_type' ) ); + + + $message = $htmlMessage; + $header[] = 'From:' . $fromAddress; + $header[] = 'Reply-To:' . $this->config['settings']['reg_org_from_email']; + wp_mail( $to, $subject, $message, $header ); + + } + + /** + * Set content type of the email. + * + * Used as filter for the wp_mail_content_type + */ + function set_content_type() + { + return 'text/html'; + } } diff --git a/setup/adminHooks.php b/setup/adminHooks.php index 7c65edf..97670c8 100644 --- a/setup/adminHooks.php +++ b/setup/adminHooks.php @@ -42,3 +42,24 @@ add_filter('glm-member-db-admin-management-hooksHelp', function($content) { 10, 2 ); + +/** + * Setup cron task request to run SendMessagesEmails + * + * Run only once per day. Everyday. + */ +// add_filter( +// 'glm_associate_cron_request', +// function( $cron_task ){ +// $new_cron = array( +// array( +// 'menu' => 'ajax', +// 'action' => 'SendMessagesEmails', +// 'daysOfWeek' => false, +// 'times' => false, +// 'params' => array() +// ) +// ); +// return array_merge( $cron_task, $new_cron ); +// } +// ); diff --git a/setup/databaseScripts/create_database_V0.0.1.sql b/setup/databaseScripts/create_database_V0.0.2.sql similarity index 90% rename from setup/databaseScripts/create_database_V0.0.1.sql rename to setup/databaseScripts/create_database_V0.0.2.sql index 0633681..0877c84 100644 --- a/setup/databaseScripts/create_database_V0.0.1.sql +++ b/setup/databaseScripts/create_database_V0.0.2.sql @@ -1,6 +1,6 @@ -- Gaslight Media Members Database -- File Created: 5/24/19 --- Database Version: 0.0.1 +-- Database Version: 0.0.2 -- Database Creation Script - Messages Add-On -- -- To permit each query below to be executed separately, @@ -23,6 +23,7 @@ CREATE TABLE {prefix}email_messages ( -- Logs CREATE TABLE {prefix}email_logs ( id INT NOT NULL AUTO_INCREMENT, + message_id INT NOT NULL, to_email TINYTEXT NOT NULL, subject TINYTEXT NOT NULL, from_email TINYTEXT NOT NULL, @@ -37,12 +38,13 @@ CREATE TABLE {prefix}email_logs ( -- Queue CREATE TABLE {prefix}email_queue ( id INT NOT NULL AUTO_INCREMENT, + message_id INT NOT NULL, to_email TINYTEXT NOT NULL, subject TINYTEXT NOT NULL, from_email TINYTEXT NOT NULL, reply_to_email TINYTEXT NULL, message_body TEXT NOT NULL, - send_date DATETIME NOT NULL, + queue_date DATETIME NOT NULL, processed BOOLEAN DEFAULT false, PRIMARY KEY (id) ); diff --git a/setup/databaseScripts/dbVersions.php b/setup/databaseScripts/dbVersions.php index 110fc98..e6b41c1 100644 --- a/setup/databaseScripts/dbVersions.php +++ b/setup/databaseScripts/dbVersions.php @@ -15,5 +15,6 @@ $glmMembersMessagesDbVersions = array( '0.0.1' => array('version' => '0.0.1', 'tables' => 2, 'date' => '05/24/2019'), + '0.0.2' => array('version' => '0.0.2', 'tables' => 3, 'date' => '05/30/2019'), ); diff --git a/setup/databaseScripts/update_database_V0.0.2.sql b/setup/databaseScripts/update_database_V0.0.2.sql new file mode 100644 index 0000000..0a99424 --- /dev/null +++ b/setup/databaseScripts/update_database_V0.0.2.sql @@ -0,0 +1,27 @@ +-- Gaslight Media Members Database - Messages Add-On +-- File Created: 5/30/2019 +-- Database Version: 0.0.2 +-- Database Update From Previous Version Script +-- +-- To permit each query below to be executed separately, +-- all queries must be separated by a line with four dashses + + +-- Add message_id to log table +ALTER TABLE {prefix}email_logs ADD COLUMN message_id INT NOT NULL; + +---- + +-- Queue +CREATE TABLE {prefix}email_queue ( + id INT NOT NULL AUTO_INCREMENT, + message_id INT NOT NULL, + to_email TINYTEXT NOT NULL, + subject TINYTEXT NOT NULL, + from_email TINYTEXT NOT NULL, + reply_to_email TINYTEXT NULL, + message_body TEXT NOT NULL, + queue_date DATETIME NOT NULL, + processed BOOLEAN DEFAULT false, + PRIMARY KEY (id) +); diff --git a/views/admin/messages/list.html b/views/admin/messages/list.html index 233414a..470c5b7 100644 --- a/views/admin/messages/list.html +++ b/views/admin/messages/list.html @@ -8,7 +8,7 @@ Subject Last Updated Sent - Stats + Queued @@ -19,7 +19,7 @@ {$message.subject} {$message.last_updated.timestamp|date_format:"%D %r"} - + {$message.stats} {/foreach} {/if} diff --git a/views/admin/messages/search.html b/views/admin/messages/search.html index a67b06d..e7fa420 100644 --- a/views/admin/messages/search.html +++ b/views/admin/messages/search.html @@ -22,8 +22,9 @@ -- 2.17.1