--- /dev/null
+<?php
+/**
+ * GLM Member-DB WordPress Add-On Plugin
+ * Data Class Email Messages
+ *
+ * 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 GlmDataEmailLogs 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 $postOpens = 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_logs';
+
+ /*
+ * Table Data Fields
+ */
+
+ $this->fields = [
+
+ 'id' => [
+ 'field' => 'id',
+ 'type' => 'integer',
+ 'view_only' => true,
+ 'use' => 'a'
+ ],
+
+ // process id
+ 'process_id' => [
+ 'field' => 'process_id',
+ 'type' => 'text',
+ 'required' => false,
+ 'use' => 'a'
+ ],
+
+ // send date
+ 'send_date' => [
+ 'field' => 'send_date',
+ 'type' => 'date',
+ 'required' => false,
+ 'use' => 'a'
+ ],
+
+ // Message id
+ 'message_id' => [
+ 'field' => 'message_id',
+ 'type' => 'pointer',
+ 'p_table' => GLM_MEMBERS_MESSAGES_PLUGIN_DB_PREFIX . 'email_messages',
+ 'p_field' => 'subject',
+ 'p_orderby' => 'subject',
+ 'force_list' => false,
+ 'required' => false,
+ '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)
+ {
+ if ( $this->postOpens ) {
+ $opens = $this->wpdb->get_var(
+ $this->wpdb->prepare(
+ "SELECT count(*)
+ FROM " . GLM_MEMBERS_MESSAGES_PLUGIN_DB_PREFIX . "email_logs
+ WHERE process_id = %s
+ AND read_date IS NOT NULL",
+ $r['process_id']
+ )
+ );
+ $r['opens'] = ( $opens ) ? $opens : '0';
+ }
+ return $r;
+ }
+
+
+}
'use' => 'a',
),
- // Member Type
+ // Template Id
'template_id' => array (
'field' => 'template_id',
'type' => 'pointer',
*/
/**
- * This class handles the work of creating new invoices based on.
- * 1) Member Type of member matching a paid invoiceType
- * 2) Member renewal date past
- * 3) Member has Billing Account
- * 4) Member has no active Invoice
- * 5) Renewal date is within the next 30 Days
- *
+ * Ajax previewer for Email messages
*/
class GlmMembersAdmin_ajax_ajaxMessagePreview extends GlmMembersAdmin_messages_index
{
*/
/**
- * This class handles the work of creating new invoices based on.
- * 1) Member Type of member matching a paid invoiceType
- * 2) Member renewal date past
- * 3) Member has Billing Account
- * 4) Member has no active Invoice
- * 5) Renewal date is within the next 30 Days
- *
+ * Track the email opens
*/
class GlmMembersAdmin_ajax_trackMessagePixel
{
// 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';
+require_once GLM_MEMBERS_MESSAGES_PLUGIN_CLASS_PATH.'/data/dataEmailLogs.php';
/*
* This class performs the work for the default action of the "Members" menu
$option = '';
$option2 = false;
$viewPath = 'admin/messages/';
+ // Merge Tags
$mergeTags = [
// 'Member Name', '{$member.name}',
'Contact First Name', '{$contact.fname}',
// 'Contact Home Phone', '{$contact.home_phone}',
// 'Contact Mobile Phone', '{$contact.mobile_phone}',
];
+ // For Paging
+ $paging = true;
+ $start = 1;
+ $limit = 20;
+ $numbDisplayed = false;
+ $lastDisplayed = false;
+ $prevStart = false;
+ $nextStart = false;
// Setup Foundation 6
wp_enqueue_style( 'Foundation6', GLM_MEMBERS_PLUGIN_URL . 'css/foundation-6.min.css' );
switch ( $option ) {
case 'stats':
$view = 'stats';
+ $whereParts = [
+ 'process_id IS NOT NULL'
+ ];
+ $where = false;
+ if ( isset( $_REQUEST['filterMessage'] ) && $filterMessage = filter_var( $_REQUEST['filterMessage'], FILTER_SANITIZE_STRING) ) {
+ $whereParts[] = " message_id IN ( SELECT id FROM " . GLM_MEMBERS_MESSAGES_PLUGIN_DB_PREFIX . "email_messages WHERE subject like '%" . $filterMessage . "%')";
+ }
+ // Check if we're doing paging (must be done before getList or getResults)
+ if ( isset( $_REQUEST['pageSelect'] ) ) {
+
+ // If request is for Next
+ if ( $_REQUEST['pageSelect'][0] == 'N' ) {
+ $newStart = $_REQUEST['nextStart'] - 0;
+
+ // Otherwise it must be Previous
+ } else {
+ $newStart = $_REQUEST['prevStart'] - 0;
+ }
+
+ if ( $newStart > 0 ) {
+ $start = $newStart;
+ }
+ }
+ if ( !empty( $whereParts ) ) {
+ $where = implode( ' AND ', $whereParts );
+ }
+ // Get logs
+ $Stats = new GlmDataEmailLogs( $this->wpdb, $this->config );
+ $Stats->postOpens = true;
+ $statsData = $Stats->getResults(
+ [
+ 'where' => $where,
+ 'groupby' => [
+ 'aggregate' => 'count(*) as emails',
+ 'group' => 'process_id',
+ ],
+ 'start' => $start,
+ 'limit' => $limit,
+ 'stats' => true,
+ ]
+ );
+ $statCount = $statsData['stats'];
+ // echo '<pre>$statCount: ' . print_r( $statCount, true ) . '</pre>';
+ $Stats->postOpens = false;
+ // Get paging results (after getList or getResults)
+ $numbDisplayed = $statsData['returned'];
+ $lastDisplayed = $statsData['last'];
+ if ( $start == 1 ) {
+ $prevStart = false;
+ } else {
+ $prevStart = $start - $limit;
+ if ( $start < 1 ) {
+ $start = 1;
+ }
+ }
+ if ( $numbDisplayed == $limit ) {
+ $nextStart = $start + $limit;
+ }
+ if ( $statCount <= $limit ) {
+ $paging = false;
+ } else {
+ $paging = [
+ 'unitName' => 'Stats',
+ 'start' => $start,
+ 'limit' => $limit,
+ 'numbDisplayed' => $numbDisplayed,
+ 'lastDisplayed' => $lastDisplayed,
+ 'prevStart' => $prevStart,
+ 'nextStart' => $nextStart,
+ ];
+ }
+ $stats = $statsData['list'];
+ $messageData = $this->wpdb->get_results(
+ "SELECT id,subject
+ FROM " . GLM_MEMBERS_MESSAGES_PLUGIN_DB_PREFIX . "email_messages
+ ORDER BY subject"
+ );
+ $messages = array();
+ foreach ( $messageData as $row ) {
+ $messages[$row->id] = $row->subject;
+ }
$tData = [
- 'stats' => 'test'
+ 'stats' => $stats,
+ 'messages' => $messages,
+ 'headers' => [
+ 'Message',
+ 'Date Sent',
+ 'Total Sent',
+ 'Opens',
+ ],
+ 'paging' => $paging,
];
break;
case 'search':
$view = 'list';
default:
+ // Check if we're doing paging (must be done before getList or getResults)
+ if ( isset( $_REQUEST['pageSelect'] ) ) {
+
+ // If request is for Next
+ if ( $_REQUEST['pageSelect'][0] == 'N' ) {
+ $newStart = $_REQUEST['nextStart'] - 0;
+
+ // Otherwise it must be Previous
+ } else {
+ $newStart = $_REQUEST['prevStart'] - 0;
+ }
+
+ if ( $newStart > 0 ) {
+ $start = $newStart;
+ }
+ }
+
if ( isset( $_REQUEST['filterArchived'] ) && $filterArchived = filter_var( $_REQUEST['filterArchived'], FILTER_VALIDATE_BOOLEAN ) ) {
$where = "T.archived = true";
} else {
}
$this->postStats = true;
$this->postSent = true;
- $messages = $this->getList( $where );
+ $order = 'last_updated DESC';
+ $messageCount = $this->getStats( $where );
+ $messageData = $this->getList( $where, $order, true, 'id', $start, $limit );
+ // Get paging results (after getList or getResults)
+ $numbDisplayed = $messageData['returned'];
+ $lastDisplayed = $messageData['last'];
+ if ( $start == 1 ) {
+ $prevStart = false;
+ } else {
+ $prevStart = $start - $limit;
+ if ( $start < 1 ) {
+ $start = 1;
+ }
+ }
+ if ( $numbDisplayed == $limit ) {
+ $nextStart = $start + $limit;
+ }
+ if ( $messageCount <= $limit ) {
+ $paging = false;
+ } else {
+ $paging = [
+ 'unitName' => 'Messages',
+ 'start' => $start,
+ 'limit' => $limit,
+ 'numbDisplayed' => $numbDisplayed,
+ 'lastDisplayed' => $lastDisplayed,
+ 'prevStart' => $prevStart,
+ 'nextStart' => $nextStart,
+ ];
+ }
+ $messages = $messageData['list'];
$this->postStats = false;
$this->postSent = false;
- $tData = array(
+ $tData = [
'messages' => $messages,
- );
+ 'paging' => $paging,
+ ];
break;
}
--- /dev/null
+<?php
+
+class Glm_REST_Messages_Controller
+{
+ public function __construct()
+ {
+ $this->namespace = '/glm/v0';
+ $this->resource_name = 'messages';
+ }
+
+ public function register_routes()
+ {
+ register_rest_route( $this->namespace, '/' . $this->resource_name, array(
+ // Here we register the readable endpoint for collections.
+ array(
+ 'methods' => 'GET',
+ 'callback' => array( $this, 'get_items' ),
+ ),
+ ) );
+ register_rest_route( $this->namespace, '/' . $this->resource_name . '/(?P<id>[\d]+)', array(
+ // Notice how we are registering multiple endpoints the 'schema' equates to an OPTIONS request.
+ array(
+ 'methods' => 'GET',
+ 'callback' => array( $this, 'get_item' ),
+ ),
+ ) );
+ }
+
+ /**
+ * Grabs the five most recent posts and outputs them as a rest response.
+ *
+ * @param WP_REST_Request $request Current request.
+ */
+ public function get_item( $request ) {
+ $id = (int) $request['id'];
+ $post = get_post( $id );
+
+ if ( empty( $post ) ) {
+ return rest_ensure_response( array() );
+ }
+
+ $response = prepare_item_for_response( $post );
+
+ // Return all of our post response data.
+ return $response;
+ }
+
+}
+
+add_action( 'rest_api_init', function(){
+ $controller = new Glm_REST_Messages_Controller();
+ $controller->register_routes();
+});
<a href="{$thisUrl}?page={$thisPage}&option=list">Email Messages</a>
</li>
<li class="{if $thisOption == 'stats'}is-active{/if}">
- <a href="{$thisUrl}?page={$thisPage}&option=stats">Stats</a>
+ <a href="{$thisUrl}?page={$thisPage}&option=stats">Campaign Stats</a>
</li>
{*
<li class="{if $thisOption == 'listTemplates' || $thisOption == 'editTemplate'}is-active{/if}">
+{* Emails Messages List view *}
+
+{* Header *}
{include file='admin/header.html'}
<h3>List Messages</h3>
{* Form Start *}
-{$ui = [
- 'id' => 'messageSearch',
- 'action' => "{$thisUrl}?page={$thisPage}",
- 'method' => 'post',
- 'file' => false
-]}
-{include file='ui/f6/form-start.html'}
-
-<input type="hidden" name="option" value="list" />
-
-<div class="grid-x grid-margin-x">
- <fieldset class="fieldset cell small-12 medium-6">
- <legend>Filter</legend>
-
- {* Show Archived *}
- {$ui = [
- 'value' => $smarty.request.filterArchived|default:'',
- 'field' => 'filterArchived',
- 'label' => 'Show Archived',
- 'required' => false,
- 'errorText' => 'Show Archived is Required',
- 'dataError' => ''
- ]}
- {include file='ui/f6/checkbox.html'}
-
- {* Submit *}
- {$ui = [
- 'class' => 'primary',
- 'label' => 'Submit',
- 'submit' => true,
- 'id' => '',
- 'cancel' => ""
- ]}
- {include file='ui/f6/submit.html'}
-
- </fieldset>
-</div>
+<form action="{$thisUrl}?page={$thisPage}" method="post" id="messageSearch">
+
+ <input type="hidden" name="option" value="list" />
+ <input type="hidden" name="prevStart" value="{$paging.prevStart}">
+ <input type="hidden" name="nextStart" value="{$paging.nextStart}">
+ <input type="hidden" name="limit" value="{$paging.limit}">
+
+ <div class="grid-x grid-margin-x">
+ <fieldset class="fieldset cell small-12 medium-6">
+ <legend>Filter</legend>
+
+ {* Show Archived *}
+ {$ui = [
+ 'value' => $smarty.request.filterArchived|default:'',
+ 'field' => 'filterArchived',
+ 'label' => 'Show Archived',
+ 'required' => false,
+ 'errorText' => 'Show Archived is Required',
+ 'dataError' => ''
+ ]}
+ {include file='ui/f6/checkbox.html'}
+
+ {* Submit *}
+ {$ui = [
+ 'class' => 'primary',
+ 'label' => 'Submit',
+ 'submit' => true,
+ 'id' => '',
+ 'cancel' => ""
+ ]}
+ {include file='ui/f6/submit.html'}
+
+ </fieldset>
+ </div>
-{* Form End *}
-{include file='ui/f6/form-end.html'}
<a href="{$thisUrl}?page={$thisPage}&option=editHtmlEmail" class="button primary">Add Message</a>
+<br>
+{* Paging *}
+{include file="ui/f6/paging.html"}
+
+{* List Messages *}
{include file='admin/messages/listMessagesTable.html'}
+{* Paging *}
+{include file="ui/f6/paging.html"}
+
+{* Form End *}
+{include file='ui/f6/form-end.html'}
+
+{* Footer *}
{include file='../../admin/footer.html'}
+{* Stats List View *}
+
+{* Header *}
{include file='admin/header.html'}
-<h3>Stats</h3>
+<h3>Campaign Stats</h3>
+
+{* Form Start *}
+<form method="post" action="{$thisUrl}?page={$thisPage}">
+ <input type="hidden" name="option" value="stats">
+ <input type="hidden" name="prevStart" value="{$paging.prevStart}">
+ <input type="hidden" name="nextStart" value="{$paging.nextStart}">
+ <input type="hidden" name="limit" value="{$paging.limit}">
+
+ <div class="grid-x grid-margin-x">
+ <fieldset class="fieldset cell small-12 medium-6">
+ <legend>Filter</legend>
+
+ {* Message *}
+ {$ui = [
+ 'value' => $smarty.request.filterMessage|default:'',
+ 'field' => 'filterMessage',
+ 'label' => 'Message',
+ 'required' => false,
+ 'errorText' => 'Message is Required',
+ 'dataError' => ''
+ ]}
+ {include file='ui/f6/text.html'}
+
+ {* Submit *}
+ {$ui = [
+ 'class' => 'primary',
+ 'label' => 'Submit',
+ 'submit' => true,
+ 'id' => '',
+ 'cancel' => ""
+ ]}
+ {include file='ui/f6/submit.html'}
+
+ </fieldset>
+ </div>
+
+ {* Paging *}
+ {include file="ui/f6/paging.html"}
+
+ <table>
+ <tr>
+ <th align="left"> Message </th>
+ <th align="left"> Date Sent </th>
+ <th align="left"> Total Sent </th>
+ <th align="left"> Opens </th>
+ </tr>
+ {foreach $stats as $campaign}
+ <tr>
+ <td> {$campaign.message_id} </td>
+ <td> {$campaign.send_date.date} </td>
+ <td> {$campaign.emails} </td>
+ <td> {$campaign.opens} </td>
+ </tr>
+ {/foreach}
+ </table>
+
+ {* Paging *}
+ {include file="ui/f6/paging.html"}
-{$stats}
+</form>
{include file='../../admin/footer.html'}