'use' => 'a'
),
+ // Has no map data
+ 'archived' => array(
+ 'field' => 'archived',
+ 'type' => 'checkbox',
+ 'use' => 'a',
+ ),
+
+ // Member Type
+ 'template_id' => array (
+ 'field' => 'template_id',
+ 'type' => 'pointer',
+ 'p_table' => GLM_MEMBERS_MESSAGES_PLUGIN_DB_PREFIX . 'email_templates',
+ 'p_field' => 'name',
+ 'p_orderby' => 'name',
+ 'required' => true,
+ 'force_list' => true,
+ 'use' => 'a'
+ ),
+
// Name
'from_email' => array (
'field' => 'from_email',
--- /dev/null
+<?php
+/**
+ * GLM Member-DB WordPress Add-On Plugin
+ * Data Class Templates
+ *
+ * PHP version 5.3
+ *
+ * @category Data
+ * @package GLM Member-DB
+ * @author Chuck Scott <cscott@gaslightmedia.com>
+ * @license http://www.gaslightmedia.com Gaslightmedia
+ * @release SVN: $Id: dataEvents.php,v 1.0 2011/01/25 19:31:47 cscott Exp $
+ */
+
+/**
+ * GlmDataEmailMessages class
+ *
+ * PHP version 5
+ *
+ * @category Data
+ * @package GLM Member DB
+ * @author Chuck Scott <cscott@gaslightmedia.com>
+ * @license http://www.gaslightmedia.com Gaslightmedia
+ * @release SVN: $Id: dataMembers.php,v 1.0 2011/01/25 19:31:47 cscott
+ * Exp $
+ */
+class GlmDataEmailTemplates extends GlmDataAbstract
+{
+
+ /**
+ * WordPress Database Object
+ *
+ * @var $wpdb
+ * @access public
+ */
+ public $wpdb;
+ /**
+ * Plugin Configuration Data
+ *
+ * @var $config
+ * @access public
+ */
+ public $config;
+ /**
+ * Data Table Name
+ *
+ * @var $table
+ * @access public
+ */
+ public $table;
+ /**
+ * Field definitions
+ *
+ * 'type' is type of field as defined by the application
+ * text Regular text field
+ * pointer Pointer to an entry in another table
+ * 'filters' is the filter name for a particular filter ID in PHP filter
+ * functions
+ * See PHP filter_id()
+ *
+ * 'use' is when to use the field
+ * l = List
+ * g = Get
+ * n = New
+ * i = Insert
+ * e = Edit
+ * u = Update
+ * d = Delete
+ * a = All
+ *
+ * @var $ini
+ * @access public
+ */
+ public $fields = false;
+
+ public $postStats = false;
+ public $postSent = false;
+
+ /**
+ * Constructor
+ *
+ * @param object $d database connection
+ * @param array $config Configuration array
+ * @param bool $limitedEdit Flag to say indicate limited edit requested
+ *
+ * @return void
+ * @access public
+ */
+ public function __construct($wpdb, $config, $limitedEdit = false)
+ {
+
+ // If this class is not being extended along with existing $wpdb and $config
+ if (!$this->wpdb) {
+
+ // Save WordPress Database object
+ $this->wpdb = $wpdb;
+
+ // Save plugin configuration object
+ $this->config = $config;
+
+ }
+
+ /*
+ * Table Name
+ */
+ $this->table = GLM_MEMBERS_MESSAGES_PLUGIN_DB_PREFIX . 'email_templates';
+
+ /*
+ * Table Data Fields
+ */
+
+ $this->fields = array (
+
+ 'id' => array (
+ 'field' => 'id',
+ 'type' => 'integer',
+ 'view_only' => true,
+ 'use' => 'a'
+ ),
+
+ // Name
+ 'name' => array (
+ 'field' => 'name',
+ 'type' => 'text',
+ 'required' => true,
+ 'use' => 'a'
+ ),
+
+ // Contacts
+ 'contents' => array (
+ 'field' => 'contents',
+ 'type' => 'text',
+ 'required' => true,
+ 'use' => 'a'
+ ),
+
+ );
+
+ }
+
+ /**
+ * Entry Post Processing Call-Back Method
+ *
+ * Perform post-processing for all result entries.
+ *
+ * In this case we're using it to append an array of category
+ * data to each member result and also sort by member name.
+ *
+ * @param array $r Array of field result data for a single entry
+ * @param string $a Action being performed (l, i, g, ...)
+ *
+ * @return object Class object
+ *
+ */
+ public function entryPostProcessing($r, $a)
+ {
+ return $r;
+ }
+
+
+}
* version from this plugin.
*/
define('GLM_MEMBERS_MESSAGES_PLUGIN_VERSION', '0.0.1');
-define('GLM_MEMBERS_MESSAGES_PLUGIN_DB_VERSION', '0.0.2');
+define('GLM_MEMBERS_MESSAGES_PLUGIN_DB_VERSION', '0.0.3');
// 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');
// Load Members data abstract
require_once GLM_MEMBERS_MESSAGES_PLUGIN_CLASS_PATH.'/data/dataEmailMessages.php';
+require_once GLM_MEMBERS_MESSAGES_PLUGIN_CLASS_PATH.'/data/dataEmailTemplates.php';
/*
* This class performs the work for the default action of the "Members" menu
'thisOption' => $option,
);
+ wp_enqueue_style( 'glmaFoundation', GLM_MEMBERS_PLUGIN_URL . '/css/glma-foundation.min.css' );
+
switch ( $option ) {
case 'search':
// echo '<pre>$this->config: ' . print_r( $this->config, true ) . '</pre>';
$searchResults = $Members->getSimpleMemberInfoList( $where );
// echo '<pre>$searchResults: ' . print_r( $searchResults, true ) . '</pre>';
- $messages = $this->getList();
+ $where = "T.archived <> true";
+ $messages = $this->getList( $where );
if ( $option2 === 'sendMessages' && isset( $_REQUEST['message_id'] ) && $messageId = filter_var( $_REQUEST['message_id'], FILTER_VALIDATE_INT ) ) {
$this->sendHtmlMessages( $searchResults, $messageId );
);
break;
- case 'list':
- $view = 'list';
- $this->postStats = true;
- $this->postSent = true;
- $messages = $this->getList();
- $this->postStats = false;
- $this->postSent = false;
- // echo '<pre>$messages: ' . print_r( $messages, true ) . '</pre>';
+ case 'listTemplates':
+ $view = 'listTemplates';
+ $Templates = new GlmDataEmailTemplates( $this->wpdb, $this->config );
+ $templates = $Templates->getList();
$tData = array(
- 'messages' => $messages,
+ 'templates' => $templates,
+ );
+ break;
+
+ case 'editTemplate':
+ $view = 'editTemplate';
+ $newEntry = false;
+ $Templates = new GlmDataEmailTemplates( $this->wpdb, $this->config );
+ if ( isset( $_REQUEST['id'] ) && $id = filter_var( $_REQUEST['id'], FILTER_VALIDATE_INT ) ) {
+ $template = $Templates->editEntry( $id );
+ } else {
+ $template = $Templates->newEntry();
+ $newEntry = true;
+ }
+ $tData = array(
+ 'template' => $template,
+ 'newEntry' => $newEntry,
);
break;
+ case 'updateTemplate':
+ echo '<pre>'.print_r($_REQUEST, true).'</pre>';
+ $Templates = new GlmDataEmailTemplates( $this->wpdb, $this->config );
+ if ( isset( $_REQUEST['id'] ) && $id = filter_var( $_REQUEST['id'], FILTER_VALIDATE_INT ) ) {
+ $message = $Templates->updateEntry( $id );
+ } else {
+ $message = $Templates->insertEntry();
+ }
+ break;
+
+
+
case 'editHtmlEmail':
$view = 'editHtmlEmail';
$newEntry = false;
}
break;
+ case 'list':
+ $view = 'list';
default:
+ $where = "T.archived <> true";
+ $this->postStats = true;
+ $this->postSent = true;
+ $messages = $this->getList( $where );
+ $this->postStats = false;
+ $this->postSent = false;
+ $tData = array(
+ 'messages' => $messages,
+ );
break;
}
// echo '<pre>$data: ' . print_r( $data, true ) . '</pre>';
$message = $this->getEntry( $messageId );
// echo '<pre>$message: ' . print_r( $message, true ) . '</pre>';
+ // exit;
$fromEmail = $message['from_email'];
$fromName = $message['from_name'];
$replyToEmail = $message['reply_to_email'];
'lname' => $contact['lname'],
)
);
- $messageBody = $this->generateHTML( $emailData, $message['message_body'], true );
+ $messageBody = $this->generateHTML( $emailData, $message['message_body'], $message['template_id']['value'] );
// Add this to the email_queue
$this->wpdb->insert(
* @access public
* @return void
*/
- function generateHTML( $data, $view, $viewIsString = false )
+ function generateHTML( $data, $view, $template )
{
// Load Smarty Template support
}
}
+ $contents = $smarty->template->fetch( 'eval:' . $view );
- // 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
+ $Templates = new GlmDataEmailTemplates( $this->wpdb, $this->config );
+ $template = $Templates->getEntry( $template );
- // 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 );
-
- }
+ $smarty->templateAssign( 'contents', $contents );
+ $out = $smarty->template->fetch( 'eval:' . $template['contents'] );
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';
- }
}
-- email_messages
CREATE TABLE {prefix}email_messages (
id INT NOT NULL AUTO_INCREMENT,
+ template_id INT NOT NULL,
+ archived BOOLEAN DEFAULT false,
from_email TINYTEXT NOT NULL,
from_name TINYTEXT NULL,
reply_to_email TINYTEXT NULL,
reply_to_email TINYTEXT NULL,
message_body TEXT NOT NULL,
send_date DATETIME NOT NULL,
+ email_read BOOLEAN DEFAULT false,
+ read_date DATETIME NULL,
PRIMARY KEY (id)
);
processed BOOLEAN DEFAULT false,
PRIMARY KEY (id)
);
+
+----
+
+-- Template
+CREATE TABLE {prefix}email_templates (
+ id INT NOT NULL AUTO_INCREMENT,
+ name TEXT NOT NULL,
+ contents TEXT NOT NULL,
+ PRIMARY KEY (id)
+);
$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'),
+ '0.0.3' => array('version' => '0.0.3', 'tables' => 4, 'date' => '06/04/2019'),
);
--- /dev/null
+-- 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 template_id to messages
+ALTER TABLE {prefix}email_messages ADD COLUMN template_id INT NOT NULL;
+
+----
+
+-- Add archived to messages
+ALTER TABLE {prefix}email_messages ADD COLUMN archived BOOLEAN DEFAULT false;
+
+----
+
+-- Add email_read to log table
+ALTER TABLE {prefix}email_logs ADD COLUMN email_read BOOLEAN DEFAULT false;
+
+----
+
+-- Add read_date to log table
+ALTER TABLE {prefix}email_logs ADD COLUMN read_date DATETIME NULL;
+
+----
+
+-- Template
+CREATE TABLE {prefix}email_templates (
+ id INT NOT NULL AUTO_INCREMENT,
+ name TEXT NOT NULL,
+ contents TEXT NOT NULL,
+ PRIMARY KEY (id)
+);
<h2 class="nav-tab-wrapper">
<a href="{$thisUrl}?page={$thisPage}&option=search" class="nav-tab{if $thisOption==search} nav-tab-active{/if}">Search</a>
- <a href="{$thisUrl}?page={$thisPage}&option=list" class="nav-tab{if $thisOption==list} nav-tab-active{/if}">HTML Messages</a>
- <a href="{$thisUrl}?page={$thisPage}&option=editHtmlEmail" class="nav-tab{if $thisOption==editHtmlEmail} nav-tab-active{/if}">Add HTML Email</a>
+ <a href="{$thisUrl}?page={$thisPage}&option=list" class="nav-tab{if $thisOption==list} nav-tab-active{/if}">Email Messages</a>
+ <a href="{$thisUrl}?page={$thisPage}&option=listTemplates" class="nav-tab{if $thisOption==listTemplates} nav-tab-active{/if}">Email Templates</a>
</h2>
- <div id="glm-admin-content-container">
+<div id="glm-admin-content-container" style="width: 1024px;">
<table>
+ <tr>
+ <th {if $message.fieldRequired.archived}class="glm-required"{/if}></th>
+ <td {if $message.fieldFail.archived}class="glm-form-bad-input" data-tabid="glm-message-template_id"{/if}>
+ <input type="checkbox" name="archived"{if $message.fieldData.archived.value} checked{/if}> Archived
+ </td>
+ </tr>
+ <tr>
+ <th {if $message.fieldRequired.from_name}class="glm-required"{/if}> Template </th>
+ <td {if $message.fieldFail.from_name}class="glm-form-bad-input" data-tabid="glm-message-template_id"{/if}>
+ <select name="template_id">
+ {foreach from=$message.fieldData.template_id.list item=v}
+ <option value="{$v.value}"{if $v.default} selected="selected"{/if}>{$v.name}</option>
+ {/foreach}
+ </select>
+ {if $message.fieldFail.template_id}<p>{$message.fieldFail.template_id}</p>{/if}
+ </td>
+ </tr>
<tr>
<th {if $message.fieldRequired.from_name}class="glm-required"{/if}>From Name:</th>
<td {if $message.fieldFail.from_name}class="glm-form-bad-input" data-tabid="glm-message-from_name"{/if}>
--- /dev/null
+<h2>Html Email</h2>
+{include file='admin/header.html'}
+
+<form action="{$thisUrl}?page={$thisPage}" method="post">
+ <input type="hidden" name="option" value="updateTemplate" />
+ {if !$newEntry}
+ <input type="hidden" name="id" value="{$template.fieldData.id}" />
+ {/if}
+
+ <table>
+
+ <tr>
+ <th {if $template.fieldRequired.name}class="glm-required"{/if}>Name:</th>
+ <td {if $template.fieldFail.name}class="glm-form-bad-input" data-tabid="glm-template-name"{/if}>
+ <input type="text" name="name" class="glm-form-text-input" value="{$template.fieldData.name|escape}" {if $template.fieldRequired.name}required{/if} />
+ </td>
+ </tr>
+ <tr>
+ <th {if $template.fieldRequired.contents}class="glm-required"{/if}>Content:</th>
+ <td {if $template.fieldFail.contents}class="glm-form-bad-input" data-tabid="glm-template-contents"{/if}>
+ {if $template}
+ {$textAreaContent = $template.fieldData.contents}
+ {else}
+ {$textAreaContent = ''}
+ {/if}
+ {wp_editor(
+ $textAreaContent,
+ 'contents',
+ json_decode('{
+ "media_buttons": true,
+ "quicktags": false,
+ "textarea_name": "contents",
+ "editor_height": 250
+ }', true)
+ )}
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2">
+ <p>Place {literal}{$contents}{/literal} where you want the Email Message to be inserted to.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2">
+ <input type="submit" class="button button-primary" value="Save" />
+ </td>
+ </tr>
+
+ </table>
+
+</form>
+
+{include file='admin/footer.html'}
{include file='admin/header.html'}
-<ul>
- <li>
- <a href="{$thisUrl}?page={$thisPage}&option=list">HTML Messages</a>
- </li>
- <li>
- <a href="{$thisUrl}?page={$thisPage}&option=search">Search Members</a>
- </li>
- <li>
- <a href="{$thisUrl}?page={$thisPage}&option=editHtmlEmail" class="button glm-right">Add HTML Email</a>
- </li>
-</ul>
+<div class="glma-row">
+ <div class="glma-large-8 glma-columns">
+ <form action="{$thisUrl}?page={$thisPage}" method="get">
+ <input type="hidden" name="page" value="{$thisPage}" />
+ <input type="hidden" name="option" value="searchMessages" />
+ <table>
+ <tr>
+ <td>
+ <input name="filterMessageName" />
+ </td>
+ <td>
+ <input type="submit" value="Search" />
+ </td>
+ </tr>
+ </table>
+ </form>
+ </div>
+ <div class="glma-large-4 glma-columns">
+ <div class="glma-row">
+ <div class="glma-small-5 glma-columns">
+ <a href="{$thisUrl}?page={$thisPage}&option=editHtmlEmail" class="button button-primary">Add Message</a>
+ </div>
+ <div class="glma-small-5 glma-columns">
+ <a href="{$thisUrl}?page={$thisPage}&option=editTemplate" class="button button-primary">Add Template</a>
+ </div>
+ </div>
+ </div>
+</div>
-This is your dashboard
-
-<div id="glm-messages-app"></div>
-
-{* React Part
-<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
-<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
-<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
-<script type="text/babel">
- ReactDOM.render(
- <h1>Hello, world!</h1>,
- document.getElementById("glm-messages-app")
- );
-</script>
-*}
+{include file='admin/messages/listMessagesTable.html'}
{include file='admin/footer.html'}
<h2>List Messages</h2>
{include file='admin/header.html'}
-<table class="wp-list-table widefat fixed posts glm-admin-table">
- <thead>
- <tr>
- <th align="left">ID</th>
- <th align="left">Subject</th>
- <th align="left">Last Updated</th>
- <th align="left">Last Sent</th>
- <th align="left">Queued</th>
- </tr>
- </thead>
- <tbody>
- {if $messages}
- {foreach $messages as $message}
- <tr>
- <td> {$message.id} </td>
- <td> <a href="{$thisUrl}?page={$thisPage}&option=editHtmlEmail&id={$message.id}">{$message.subject}</a> </td>
- <td> {$message.last_updated.timestamp|date_format:"%D %r"} </td>
- <td> {$message.sent|date_format:"%D %r"} </td>
- <td> {$message.stats|date_format:"%D %r"} </td>
- </tr>
- {/foreach}
- {/if}
- </tbody>
-</table>
+{include file='admin/messages/listMessagesTable.html'}
{include file='admin/footer.html'}
--- /dev/null
+<table class="wp-list-table widefat fixed posts glm-admin-table" style="width: 800px;">
+ <thead>
+ <tr>
+ <th align="left" style="width: 20px">ID</th>
+ <th align="left">Subject</th>
+ <th align="left">Last Updated</th>
+ <th align="left">Last Sent</th>
+ <th align="left">Queued</th>
+ </tr>
+ </thead>
+ <tbody>
+ {if $messages}
+ {foreach $messages as $message}
+ <tr>
+ <td> {$message.id} </td>
+ <td> <a href="{$thisUrl}?page={$thisPage}&option=editHtmlEmail&id={$message.id}">{$message.subject}</a> </td>
+ <td> {$message.last_updated.timestamp|date_format:"%D %r"} </td>
+ <td> {$message.sent|date_format:"%D %r"} </td>
+ <td> {$message.stats|date_format:"%D %r"} </td>
+ </tr>
+ {/foreach}
+ {/if}
+ </tbody>
+</table>
--- /dev/null
+<h2>List Messages</h2>
+{include file='admin/header.html'}
+
+<table class="wp-list-table widefat fixed posts glm-admin-table" style="width: 800px;">
+ <thead>
+ <tr>
+ <th align="left" style="width: 20px">ID</th>
+ <th align="left">Name</th>
+ </tr>
+ </thead>
+ <tbody>
+ {if $templates}
+ {foreach $templates as $template}
+ <tr>
+ <td> {$template.id} </td>
+ <td> <a href="{$thisUrl}?page={$thisPage}&option=editTemplate&id={$template.id}">{$template.name}</a> </td>
+ </tr>
+ {/foreach}
+ {/if}
+ </tbody>
+</table>
+
+{include file='admin/footer.html'}
{/if}
{if $searchResults}
- <table class="wp-list-table widefat fixed posts glm-admin-table">
+ <table class="wp-list-table widefat fixed posts glm-admin-table" style="width: 800px;">
<thead>
<tr>
<th>ID</th>