DB updates and member leads search with csv export.
authorSteve Sutton <steve@gaslightmedia.com>
Thu, 31 May 2018 18:59:18 +0000 (14:59 -0400)
committerSteve Sutton <steve@gaslightmedia.com>
Thu, 31 May 2018 18:59:18 +0000 (14:59 -0400)
CSV Export
Db update for searches table.
more styling.

17 files changed:
assets/csv.png [new file with mode: 0755]
assets/pdf.png [new file with mode: 0755]
classes/data/dataLeads.php
classes/data/dataLeadsReferredBy.php
css/admin.css
index.php
models/admin/ajax/leadCsvExport.php [new file with mode: 0644]
models/admin/travel/index.php
models/admin/travel/members.php
setup/databaseScripts/create_database_V0.0.2.sql [deleted file]
setup/databaseScripts/create_database_V0.0.3.sql [new file with mode: 0644]
setup/databaseScripts/dbVersions.php
setup/databaseScripts/update_database_V0.0.3.sql [new file with mode: 0644]
setup/validActions.php
views/admin/travel/edit.html
views/admin/travel/memberSearchForm.html
views/admin/travel/members.html

diff --git a/assets/csv.png b/assets/csv.png
new file mode 100755 (executable)
index 0000000..3a88353
Binary files /dev/null and b/assets/csv.png differ
diff --git a/assets/pdf.png b/assets/pdf.png
new file mode 100755 (executable)
index 0000000..e941d10
Binary files /dev/null and b/assets/pdf.png differ
index 0875226..87fdfc8 100644 (file)
@@ -12,6 +12,9 @@
  * @release  SVN: $Id: dataLeads.php,v 1.0 2011/01/25 19:31:47 cscott Exp $
  */
 
+require_once GLM_MEMBERS_TRAVEL_PLUGIN_CLASS_PATH . '/data/dataNotes.php';
+require_once GLM_MEMBERS_TRAVEL_PLUGIN_CLASS_PATH . '/data/dataContacts.php';
+require_once GLM_MEMBERS_TRAVEL_PLUGIN_CLASS_PATH . '/data/dataLeadsReferredBy.php';
 /**
  * GlmDataLeads class
  *
@@ -72,6 +75,18 @@ class GlmDataTravelLeads extends GlmDataAbstract
      * @access public
      */
     public $fields = false;
+    /**
+     * Add Notes
+     */
+    public $postAddNotes = false;
+    /**
+     * Add Contacts
+     */
+    public $postAddContacts = false;
+    /**
+     * Add Referredby
+     */
+    public $postAddReferredby = false;
 
     /**
      * Constructor
@@ -232,13 +247,6 @@ class GlmDataTravelLeads extends GlmDataAbstract
                 'use'       => 'a',
             ),
 
-            // 'member_ok' => array(
-            //     'field'     => 'member_ok',
-            //     'type'      => 'checkbox',
-            //     'required'  => false,
-            //     'use'       => 'a',
-            // ),
-
          );
 
     }
@@ -259,6 +267,24 @@ class GlmDataTravelLeads extends GlmDataAbstract
      */
     public function entryPostProcessing($r, $a)
     {
+        if ( $this->postAddNotes ) {
+            // Grab this leads notes into one field.
+            $Notes = new GlmDataTravelNotes( $this->wpdb, $this->config );
+            $notes = $Notes->getList( "T.lead = {$r['id']}", "T.updated DESC" );
+            $r['notes'] = $notes;
+        }
+        if ( $this->postAddContacts ) {
+            // Grab this leads notes into one field.
+            $Contacts = new GlmDataTravelContacts( $this->wpdb, $this->config );
+            $contacts = $Contacts->getList( "T.lead = {$r['id']}", "T.updated DESC" );
+            $r['contacts'] = $contacts;
+        }
+        if ( $this->postAddReferredby ) {
+            // Grab this leads notes into one field.
+            $ReferredBy = new GlmDataTravelLeadsReferredBy( $this->wpdb, $this->config );
+            $refs = $ReferredBy->getList( "T.lead = {$r['id']}", "referredby_name" );
+            $r['refs'] = $refs;
+        }
         return $r;
     }
 
index 1218f3f..e74185f 100644 (file)
@@ -137,6 +137,18 @@ class GlmDataTravelLeadsReferredBy extends GlmDataAbstract
                 'use'       => 'a',
             ),
 
+            'referredby_name' => array(
+                'field'     => 'referredby',
+                'type'      => 'pointer',
+                'as'        => 'referredby_name',
+                'p_table'   => GLM_MEMBERS_TRAVEL_PLUGIN_DB_PREFIX . 'referredby',
+                'p_field'   => 'name',
+                'p_orderby' => 'name',
+                'p_blank'   => true,
+                'required'  => true,
+                'use'       => 'a',
+            ),
+
          );
 
     }
index 690a4cc..1001f96 100644 (file)
@@ -341,24 +341,84 @@ div.webform table, div.webform td {
 
 /* Member travel leads */
 #file_export fieldset {
-    border-width: 2px;
-    border-style: groove;
-    border-color: grey;
-    position: relative;
-    width: 90%;
+    /* border-width: 2px; */
+    /* border-style: groove; */
+    /* border-color: grey; */
+    /* position: relative; */
+    /* width: 90%; */
+    /* padding: 30px; */
+}
+.clearfix {
+    display: inline-block;
+    /* overflow: auto; */
 }
 .clearfix:after {
     content: "";
-    display: block;
     clear: both;
+    display: block;
+    font-size: 0;
     height: 0;
-    line-height: 0;
     visibility: hidden;
 }
-
+#file_export .row-container {
+    position: relative;
+    float: none;
+    display: block;
+    width: 100%;
+    height: auto;
+    clear: both;
+}
 #file_export .field-container {
     display: block;
     position: relative;
     float: left;
     width: 48%;
 }
+#file_export .field-container label {
+    width: 100%;
+    display: inline-block;
+}
+
+
+/* Members Travel Leads */
+
+#intTogParent, #disTogParent, #intTogParent2, #intTogParent1, #locTogParent {
+       cursor: pointer;
+       background: #eee;
+       padding: 10px;
+       }
+#intTogParent:before, #disTogParent:before, #intTogParent2:before, #intTogParent1:before , #locTogParent:before{
+       content: "+ ";
+       }
+#file_export label.label {
+       margin-right: 10px;
+       width: 60px;
+       display: block;
+       float: left;
+       line-height: 24px;
+       }
+#file_export fieldset>div {
+       padding: 10px 0 0 10px;
+       margin-bottom: 10px;
+       height: 1%;
+       overflow: hidden;
+       }
+#file_export h3 {
+       margin: 0;
+       padding-top: 1em;
+       font-size: 13px;
+       clear: left;
+}
+#file_export .glmCheckBox {
+       width: 300px;
+       }
+#file_export fieldset>div>.glmCheckBox  {
+       width: 260px;
+       }
+#file_export fieldset>div>.glmCheckBox input {
+       float: left;
+       }
+#file_export fieldset>div>.glmCheckBox span {
+       padding-left: 30px;
+       display: block;
+       }
index 743e580..b827350 100644 (file)
--- a/index.php
+++ b/index.php
@@ -44,7 +44,7 @@ if (!defined('ABSPATH')) {
  *  version from this plugin.
  */
 define('GLM_MEMBERS_TRAVEL_PLUGIN_VERSION', '0.0.1');
-define('GLM_MEMBERS_TRAVEL_PLUGIN_DB_VERSION', '0.0.2');
+define('GLM_MEMBERS_TRAVEL_PLUGIN_DB_VERSION', '0.0.3');
 
 // This is the minimum version of the GLM Members DB plugin require for this plugin.
 define('GLM_MEMBERS_TRAVEL_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION', '2.8.0');
diff --git a/models/admin/ajax/leadCsvExport.php b/models/admin/ajax/leadCsvExport.php
new file mode 100644 (file)
index 0000000..9da8296
--- /dev/null
@@ -0,0 +1,308 @@
+<?php
+
+/**
+ * Gaslight Media Registrants Database
+ * Registrants List Export by AJAX
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmRegistrantsDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @version  0.1
+ */
+
+
+// Load Registrant Info data abstract
+require_once GLM_MEMBERS_TRAVEL_PLUGIN_CLASS_PATH.'/data/dataLeads.php';
+require_once GLM_MEMBERS_TRAVEL_PLUGIN_CLASS_PATH . '/data/dataContacts.php';
+require_once GLM_MEMBERS_TRAVEL_PLUGIN_CLASS_PATH . '/data/dataNotes.php';
+
+/**
+ *
+ * This class exports the currently selected registrants list
+ * to a printable HTML file, to a CSV file, or otherwise.
+ */
+class GlmMembersAdmin_ajax_leadCsvExport extends GlmDataTravelLeads
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+    /**
+     * Plugin Configuration Data
+     *
+     * @var $config
+     * @access public
+     */
+    public $config;
+
+    /**
+     * Constructor
+     *
+     * This constructor sets up this model. At this time that only includes
+     * storing away the WordPress data object.
+     *
+     * @return object Class object
+     *
+     */
+    public function __construct ($wpdb, $config)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        // Save plugin configuration object
+        $this->config = $config;
+
+        parent::__construct(false, false);
+
+    }
+
+    public function checkFlag($t) {return isset($_REQUEST[$t]) && $_REQUEST[$t] == 'on';}
+    /**
+     * Perform Model Action
+     *
+     * This modelAction takes an AJAX image upload and stores the image in the
+     * media/images directory of the plugin.
+     *
+     * This model action does not return, it simply does it's work then calls die();
+     *
+     * @param $actionData
+     *
+     * Echos JSON string as response and does not return
+     */
+    public function modelAction ($actionData = false)
+    {
+
+        $where   = ' true ';
+        $list    = false;
+        $lead_id = false;
+
+        // Get registration event ID if supplied
+        if (isset($_REQUEST['lead_id'])) {
+
+            // Make sure it's numeric
+            $lead_id = ($_REQUEST['lead_id'] - 0);
+
+        }
+
+        // Only get active leads.
+        $where_parts = array( 'T.status = ' . $this->config['lead_status_numb']['Active'] );
+
+        $search_params = filter_var_array(
+            $_REQUEST,
+            array(
+                'company'   => FILTER_SANITIZE_STRING,
+                'contact'   => FILTER_SANITIZE_STRING,
+                'from_date' => array(
+                    'filter'  => FILTER_VALIDATE_REGEXP,
+                    'options' => array(
+                        'regexp' => '%([0-9]{2})/([0-9]{2})/([0-9]{4})%'
+                    )
+                ),
+                'to_date' => array(
+                    'filter'  => FILTER_VALIDATE_REGEXP,
+                    'options' => array(
+                        'regexp' => '%([0-9]{2})/([0-9]{2})/([0-9]{4})%'
+                    )
+                ),
+                'state' => array(
+                    'filter' => FILTER_SANITIZE_STRING,
+                    'flags'  => FILTER_FORCE_ARRAY,
+                ),
+            )
+        );
+        // echo '<pre>$search_params: ' . print_r( $search_params, true ) . '</pre>';
+        if ( $search_params['company'] ) {
+            $where_parts[] = "T.company like '%" . esc_sql( $search_params['company'] ) . "%'";
+        }
+        if ( $search_params['state'] ) {
+            $where_parts[] = "T.state in ('" . implode( "','" , $search_params['state'] ) . "')";
+        }
+        if ( $search_params['contact'] ) {
+            // Search for name.
+            // Could be in these formats:
+            // fname lname
+            // lname, fname
+            // lname fname
+            // lname
+            // fname
+            $name_parts   = array();
+            $name_parts[] = "SOUNDEX(CONCAT_WS(' ', fname, lname)) = SOUNDEX( '" . esc_sql( $search_params['contact'] ) . "')";
+            $name_parts[] = "SOUNDEX(CONCAT_WS(' ', lname, fname)) = SOUNDEX( '" . esc_sql( $search_params['contact'] ) . "')";
+            $name_parts[] = "SOUNDEX(fname) = SOUNDEX( '" . esc_sql( $search_params['contact'] ) . "')";
+            $name_parts[] = "SOUNDEX(lname) = SOUNDEX( '" . esc_sql( $search_params['contact'] ) . "')";
+            $where_parts[]  = '('.implode( ' OR ', $name_parts ).')';
+        }
+        if ( $search_params['from_date'] && $search_params['to_date'] ) {
+            $from_date = date( 'Y-m-d', strtotime( $search_params['from_date'] ) );
+            $to_date   = date( 'Y-m-d', strtotime( $search_params['to_date'] ) );
+            /*
+             * We get a date from the form in mm/dd/YYYY format.
+             * Here in mysql we reformat the date using STR_TO_DATE function.
+             */
+            $where_parts[] = "T.updated BETWEEN '{$from_date} 00:00:00' AND '{$to_date} 23:59:59'";
+        }
+
+
+        if ( $lead_id ) {
+            $where_parts[] = " T.id = $lead_id ";
+        }
+
+
+        // Get list of all registrants for this event
+        $where = implode( ' AND ', $where_parts );
+
+        // echo '<pre>$where: ' . print_r( $where, true ) . '</pre>';
+        // exit;
+
+        $this->postAddNotes      = true;
+        $this->postAddContacts   = true;
+        $this->postAddReferredby = true;
+        // Grab list of leads with notes, contacts and referredby
+        $list = $this->getList( $where, "T.company ASC,T.lname ASC,T.fname ASC,T.updated DESC" );
+
+        // echo '<pre>$list: ' . print_r( $list, true ) . '</pre>';
+        // exit;
+
+        // If we have list entries - even if it's an empty list
+        $success   = true;
+        $haveLeads = false;
+        if ($list !== false) {
+            $success = true;
+
+            // If we have any entries
+            $leadCount = count($list);
+            if ($leadCount > 0) {
+                $haveLeads = true;
+            }
+        }
+        $lead_counter = 0;
+        $out = array();
+
+        if ( $haveLeads ) {
+            foreach ( $list as $lead ) {
+                // Extra data
+                $notes       = $this->formatNotes( $lead['notes'] );
+                $contacts    = $this->formatContacts( $lead['contacts'] );
+                $referred_by = $this->formatReferredBy( $lead['refs'] );
+
+                // $out array with data for this lead
+                $out = array(
+                    'updated'     => $lead['updated']['datetime'],
+                    'fname'       => $lead['fname'],
+                    'lname'       => $lead['lname'],
+                    'address'     => $lead['address'],
+                    'address2'    => $lead['address2'],
+                    'city'        => $lead['city'],
+                    'state'       => $lead['state']['value'],
+                    'zip'         => $lead['zip'],
+                    'phone'       => $lead['phone'],
+                    'fax'         => $lead['fax'],
+                    'email'       => $lead['email'],
+                    'website'     => $lead['website'],
+                    'notes'       => $notes,
+                    'contacts'    => $contacts,
+                    'referred_by' => $referred_by,
+                );
+                // First line should be the header line
+                if ( $lead_counter === 0 ) {
+                    $csv_file_output = implode( ',', array_map( function($str){return sprintf( '"%s"', $str );}, array_keys( $out ) ) ) . "\n";
+                }
+                /*
+                 * remove any double quotes from the values and add double
+                 * quotes around all values.
+                 */
+                $csv_file_output .= implode( ',', array_map( function($str){return sprintf( '"%s"', str_replace( '"', '', $str ) );}, $out ) ) . "\n";
+                $lead_counter++;
+            }
+
+        }
+
+        // Compile template data
+        // $templateData = array(
+        //     'haveLeads' => $haveLeads,
+        //     'leads'     => $list,
+        //     'leadCount' => $leadCount,
+        // );
+
+        // $view = 'admin/ajax/leadExportCsv.html';
+
+        // Headers for file download
+        header('Content-Description: File Transfer');
+        header('Content-Type: application/force-download');
+        header("Content-Type: text/csv");
+        header("Content-Disposition: attachment; filename=file.csv");
+
+        // Disable caching
+        header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1
+        header("Pragma: no-cache"); // HTTP 1.0
+        header("Expires: 0"); // Proxies
+
+        echo $csv_file_output;
+
+        exit;
+
+        // Return status, suggested view, and data to controller
+        // return array(
+        //     'status'           => $success,
+        //     'menuItemRedirect' => false,
+        //     'modelRedirect'    => false,
+        //     'view'             => $view,
+        //     'data'             => $templateData
+        // );
+
+    }
+
+
+    public function formatNotes( $notes )
+    {
+        $ret = '';
+        $format = "%s\r%s\r";
+        foreach($notes as $log) {
+            $logMessage = preg_replace("/\n/", '', $log['notes']);
+            $logMessage = str_replace("\"", "'", $logMessage);
+            $ret .= sprintf(
+                $format,
+                $log['updated']['datetime'],
+                $logMessage
+            );
+        }
+        return $ret;
+    }
+
+    public function formatContacts( $contacts )
+    {
+        $ret = '';
+        $format = "%s %s %s\r";
+        foreach($contacts as $c) {
+            $ret .= sprintf(
+                $format,
+                $c['name'],
+                $c['email'],
+                $c['phone']
+            );
+        }
+        return $ret;
+    }
+
+    public function formatReferredBy( $refs )
+    {
+        $ret = '';
+        $format = "%s\r";
+        foreach($refs as $r) {
+            $ret .= sprintf(
+                $format,
+                $r['referredby_name']
+            );
+        }
+        return $ret;
+    }
+
+}
index d6113d6..19cea0e 100644 (file)
@@ -183,7 +183,7 @@ class GlmMembersAdmin_travel_index extends GlmDataTravelLeads
                 $name_parts[] = "SOUNDEX(CONCAT_WS(' ', lname, fname)) = SOUNDEX( '" . esc_sql( $search_params['contact'] ) . "')";
                 $name_parts[] = "SOUNDEX(fname) = SOUNDEX( '" . esc_sql( $search_params['contact'] ) . "')";
                 $name_parts[] = "SOUNDEX(lname) = SOUNDEX( '" . esc_sql( $search_params['contact'] ) . "')";
-                $where_parts[]  = implode( ' OR ', $name_parts );
+                $where_parts[]  = '('.implode( ' OR ', $name_parts ).')';
             }
 
         }
@@ -194,6 +194,8 @@ class GlmMembersAdmin_travel_index extends GlmDataTravelLeads
         // Initialize the grouped_interests array
         $grouped_interests = array();
 
+        // echo '<pre>$this->config: ' . print_r( $this->config, true ) . '</pre>';
+
         switch ( $option ) {
         case 'delete':
             // echo '<pre>$this->entryId: ' . print_r( $this->entryId, true ) . '</pre>';
@@ -290,8 +292,8 @@ class GlmMembersAdmin_travel_index extends GlmDataTravelLeads
                 }
                 $order = "T.lname, T.fname";
             }
-            echo '<pre>$where: ' . print_r( $where, true ) . '</pre>';
-            echo '<pre>$order: ' . print_r( $order, true ) . '</pre>';
+            // echo '<pre>$where: ' . print_r( $where, true ) . '</pre>';
+            // echo '<pre>$order: ' . print_r( $order, true ) . '</pre>';
             // Check if we're doing paging
             if (isset($_REQUEST['pageSelect'])) {
                 // If request is for Next
index d3c91c6..7b7ca9a 100644 (file)
@@ -91,7 +91,7 @@ class GlmMembersAdmin_travel_members extends GlmDataTravelLeads
         $search_id           = false;
         $numbDisplayed       = false;
         $lastDisplayed       = false;
-        $paging              = true;
+        $paging              = false;
         $prevStart           = false;
         $nextStart           = false;
         $start               = 1;
@@ -150,27 +150,104 @@ class GlmMembersAdmin_travel_members extends GlmDataTravelLeads
             }
         }
 
-        $where_parts = array( 'T.status = 10' );
+        // See if they have a saved search to use.
+        if ( isset( $wpUser ) && $wpUser ) {
+            $result = $this->wpdb->get_row(
+                $this->wpdb->prepare(
+                    "SELECT *
+                       FROM " . GLM_MEMBERS_TRAVEL_PLUGIN_DB_PREFIX . "searches
+                      WHERE user_id = %d",
+                    $wpUser['ID']
+                ),
+                ARRAY_A
+            );
+            if ( $result ) {
+                $search_id = $result['id'];
+                if ( !isset( $_REQUEST['search'] ) ) {
+                    $search_params = unserialize( $result['search'] );
+                }
+            }
+        }
+
+        // Get from and to date from request
+        if ( !isset( $_REQUEST['from_date'] ) ) {
+            $_REQUEST['from_date'] = date( 'm/d/Y' );
+        }
+        if ( !isset( $_REQUEST['to_date'] ) ) {
+            $_REQUEST['to_date'] = date( 'm/d/Y' );
+        }
+
+        // Only get active leads.
+        $where_parts = array( 'T.status = ' . $this->config['lead_status_numb']['Active'] );
 
-        if ( ( isset( $search ) && $search ) ) {
+        // echo '<pre>$_REQUEST: ' . print_r( $_REQUEST, true ) . '</pre>';
+
+        if ( ( isset( $search ) && $search ) || isset( $search_params ) && $search_params ) {
             if ( isset( $search ) && $search ) {
                 $searching = true;
             }
             // Filter the $_POST variables from the search form.
             // Verify mm/dd/YYYY date format for the from and to dates.
-            $search_params = filter_var_array(
-                $_REQUEST,
-                array(
-                    'company'   => FILTER_SANITIZE_STRING,
-                    'contact'   => FILTER_SANITIZE_STRING,
-                )
-            );
+            if ( !isset( $search_params ) ) {
+                $search_params = filter_var_array(
+                    $_REQUEST,
+                    array(
+                        'company'   => FILTER_SANITIZE_STRING,
+                        'contact'   => FILTER_SANITIZE_STRING,
+                        'from_date' => array(
+                            'filter'  => FILTER_VALIDATE_REGEXP,
+                            'options' => array(
+                                'regexp' => '%([0-9]{2})/([0-9]{2})/([0-9]{4})%'
+                            )
+                        ),
+                        'to_date' => array(
+                            'filter'  => FILTER_VALIDATE_REGEXP,
+                            'options' => array(
+                                'regexp' => '%([0-9]{2})/([0-9]{2})/([0-9]{4})%'
+                            )
+                        ),
+                        'state' => array(
+                            'filter' => FILTER_SANITIZE_STRING,
+                            'flags'  => FILTER_FORCE_ARRAY,
+                        ),
+                    )
+                );
+            }
+// echo '<pre>$search_params: ' . print_r( $search_params, true ) . '</pre>';
+
+            // If we have wpUser then save searches for them.
+            if ( $wpUser['ID'] ) {
+                $search_data = array(
+                    'title'   => 'Travel Lead Search',
+                    'updated' => date( 'Y-m-d H:i:s' ),
+                    'user_id' => $wpUser['ID'],
+                    'search'  => serialize( $search_params ),
+                );
+                if ( $search_id ) {
+                    $this->wpdb->update(
+                        GLM_MEMBERS_TRAVEL_PLUGIN_DB_PREFIX . 'searches',
+                        $search_data,
+                        array( 'id' => $search_id ),
+                        array( '%s', '%s', '%d', '%s' ),
+                        array( '%d' )
+                    );
+                } else  {
+                    $this->wpdb->insert(
+                        GLM_MEMBERS_TRAVEL_PLUGIN_DB_PREFIX . 'searches',
+                        $search_data,
+                        array( '%s', '%s', '%d', '%s' )
+                    );
+                }
+            }
 
             // build the $where part
             // echo '<pre>$search_params: ' . print_r( $search_params, true ) . '</pre>';
             if ( $search_params['company'] ) {
                 $where_parts[] = "T.company like '%" . esc_sql( $search_params['company'] ) . "%'";
             }
+            if ( $search_params['state'] ) {
+                $where_parts[] = "T.state in ('" . implode( "','" , $search_params['state'] ) . "')";
+            }
             if ( $search_params['contact'] ) {
                 // Search for name.
                 // Could be in these formats:
@@ -184,7 +261,16 @@ class GlmMembersAdmin_travel_members extends GlmDataTravelLeads
                 $name_parts[] = "SOUNDEX(CONCAT_WS(' ', lname, fname)) = SOUNDEX( '" . esc_sql( $search_params['contact'] ) . "')";
                 $name_parts[] = "SOUNDEX(fname) = SOUNDEX( '" . esc_sql( $search_params['contact'] ) . "')";
                 $name_parts[] = "SOUNDEX(lname) = SOUNDEX( '" . esc_sql( $search_params['contact'] ) . "')";
-                $where_parts[]  = implode( ' OR ', $name_parts );
+                $where_parts[]  = '('.implode( ' OR ', $name_parts ).')';
+            }
+            if ( $search_params['from_date'] && $search_params['to_date'] ) {
+                $from_date = date( 'Y-m-d', strtotime( $search_params['from_date'] ) );
+                $to_date   = date( 'Y-m-d', strtotime( $search_params['to_date'] ) );
+                /*
+                 * We get a date from the form in mm/dd/YYYY format.
+                 * Here in mysql we reformat the date using STR_TO_DATE function.
+                 */
+                $where_parts[] = "T.updated BETWEEN '{$from_date} 00:00:00' AND '{$to_date} 23:59:59'";
             }
 
         }
@@ -197,22 +283,6 @@ class GlmMembersAdmin_travel_members extends GlmDataTravelLeads
 
         switch ( $option ) {
         default:
-            // Check for paging
-            if ( isset( $_REQUEST['pageSelect'] ) ) {
-                $_SESSION['search']['pageSelect'] = $_REQUEST['pageSelect'];
-            } else if ( isset( $_REQUEST['searched'] ) && !isset( $_REQUEST['pageSelect'] ) ) {
-                unset( $_SESSION['search']['pageSelect'] );
-            }
-            if ( isset( $_REQUEST['nextStart'] ) ) {
-                $_SESSION['search']['nextStart'] = $_REQUEST['nextStart'];
-            } else if ( isset( $_REQUEST['searched'] ) && !isset( $_REQUEST['nextStart'] ) ) {
-                unset( $_SESSION['search']['nextStart'] );
-            }
-            if ( isset( $_REQUEST['prevStart'] ) ) {
-                $_SESSION['search']['prevStart'] = $_REQUEST['prevStart'];
-            } else if ( isset( $_REQUEST['searched'] ) && !isset( $_REQUEST['prevStart'] ) ) {
-                unset( $_SESSION['search']['prevStart'] );
-            }
 
             if ( isset( $where_parts ) && !empty( $where_parts ) ) {
                 $where .= ' AND ' . implode( ' AND ', $where_parts );
@@ -270,6 +340,8 @@ class GlmMembersAdmin_travel_members extends GlmDataTravelLeads
             break;
         }
 
+        // echo '<pre>$this->config: ' . print_r( $this->config, true ) . '</pre>';
+
         // Enqueue the scripts for jqueryui
         wp_enqueue_script( 'jquery-ui-tabs' );
         wp_enqueue_style( 'jquery-ui-smoothness', 'https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.min.css' );
@@ -296,6 +368,9 @@ class GlmMembersAdmin_travel_members extends GlmDataTravelLeads
             'updating_error'  => $updating_error,
             'inserting'       => $inserting,
             'inserting_error' => $inserting_error,
+            'assetsUrl'       => GLM_MEMBERS_TRAVEL_PLUGIN_URL . 'assets',
+            'states'          => $this->config['states'],
+            'search_params'   => $search_params,
         );
 
 
diff --git a/setup/databaseScripts/create_database_V0.0.2.sql b/setup/databaseScripts/create_database_V0.0.2.sql
deleted file mode 100644 (file)
index 01c3e97..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
--- Gaslight Media Travel Leads Module
--- File Created: 05/18/2018
--- Database Version: 0.0.1
--- Database Creation Script
---
--- To permit each query below to be executed separately,
--- all queries must be separated by a line with four dashes
---
--- **** BE SURE TO ALSO UPDATE drop_database_Vxxx.sql FILE WHEN CHANGING TABLES ****
---
-
--- Leads
-CREATE TABLE {prefix}leads (
-    id INT NOT NULL AUTO_INCREMENT,
-    status INT NOT NULL DEFAULT 0,      -- Lead Status (active, inactive)
-    create_date DATE NOT NULL,          -- Date contact was created
-    updated DATETIME NOT NULL,          -- Updated Timestamp
-    fname TEXT NULL,                    -- First Name
-    lname TEXT NULL,                    -- Last Name
-    email TINYTEXT NULL,                -- Email
-    company TEXT NULL,                  -- Company Name
-    address TEXT NULL,                  -- Address
-    address2 TEXT NULL,                 -- Address 2
-    city TEXT NULL,                     -- City
-    state TEXT NULL,                    -- State
-    zip TEXT NULL,                      -- ZIP
-    phone TEXT NULL,                     -- Phone
-    fax TEXT NULL,                      -- Fax
-    mail_ok BOOLEAN DEFAULT false,      -- Mail OK (boolean)
-    website TEXT NULL,                  -- Website URL
-    PRIMARY KEY (id),
-    INDEX(create_date),
-    INDEX(email(20)),
-    INDEX(fname(20)),
-    INDEX(lname(20))
-);
-
-----
-
--- ReferredBy
-CREATE TABLE {prefix}referredby (
-    id INT NOT NULL AUTO_INCREMENT,
-    parent INT NOT NULL,                -- Pointer to the parent referredby id
-    name TINYTEXT NOT NULL,             -- Name
-    PRIMARY KEY (id),
-    INDEX(parent)
-);
-
-----
-
--- Referred By to Leads
-CREATE TABLE {prefix}leads_referredby (
-    id INT NOT NULL AUTO_INCREMENT,
-    lead INT NOT NULL,                  -- Reference to lead table
-    referredby INT NOT NULL,            -- Reference to referred by table
-    PRIMARY KEY (id),
-    INDEX(lead),
-    INDEX(referredby)
-);
-
-----
-
--- Lead Notes
-CREATE TABLE {prefix}lead_notes (
-    id INT NOT NULL AUTO_INCREMENT,
-    lead INT NOT NULL,                  -- Reference to lead table
-    created DATETIME NOT NULL,          -- Created Timestamp
-    updated DATETIME NOT NULL,          -- Updated Timestamp
-    notes TEXT,                         -- Note Entry
-    PRIMARY KEY (id),
-    INDEX(lead)
-);
-
-----
-
--- Lead Contacts
-CREATE TABLE {prefix}lead_contacts (
-    id INT NOT NULL AUTO_INCREMENT,
-    lead INT NOT NULL,                  -- Reference to lead table
-    updated DATETIME NOT NULL,          -- Updated Timestamp
-    name TINYTEXT,                      -- Name of Contact
-    email TINYTEXT,                     -- Email of Contact
-    phone TINYTEXT,                     -- Phone of Contact
-    PRIMARY KEY (id),
-    INDEX(lead)
-);
diff --git a/setup/databaseScripts/create_database_V0.0.3.sql b/setup/databaseScripts/create_database_V0.0.3.sql
new file mode 100644 (file)
index 0000000..ac012da
--- /dev/null
@@ -0,0 +1,98 @@
+-- Gaslight Media Travel Leads Module
+-- File Created: 05/18/2018
+-- Database Version: 0.0.1
+-- Database Creation Script
+--
+-- To permit each query below to be executed separately,
+-- all queries must be separated by a line with four dashes
+--
+-- **** BE SURE TO ALSO UPDATE drop_database_Vxxx.sql FILE WHEN CHANGING TABLES ****
+--
+
+-- Leads
+CREATE TABLE {prefix}leads (
+    id INT NOT NULL AUTO_INCREMENT,
+    status INT NOT NULL DEFAULT 0,      -- Lead Status (active, inactive)
+    create_date DATE NOT NULL,          -- Date contact was created
+    updated DATETIME NOT NULL,          -- Updated Timestamp
+    fname TEXT NULL,                    -- First Name
+    lname TEXT NULL,                    -- Last Name
+    email TINYTEXT NULL,                -- Email
+    company TEXT NULL,                  -- Company Name
+    address TEXT NULL,                  -- Address
+    address2 TEXT NULL,                 -- Address 2
+    city TEXT NULL,                     -- City
+    state TEXT NULL,                    -- State
+    zip TEXT NULL,                      -- ZIP
+    phone TEXT NULL,                     -- Phone
+    fax TEXT NULL,                      -- Fax
+    mail_ok BOOLEAN DEFAULT false,      -- Mail OK (boolean)
+    website TEXT NULL,                  -- Website URL
+    PRIMARY KEY (id),
+    INDEX(create_date),
+    INDEX(email(20)),
+    INDEX(fname(20)),
+    INDEX(lname(20))
+);
+
+----
+
+-- ReferredBy
+CREATE TABLE {prefix}referredby (
+    id INT NOT NULL AUTO_INCREMENT,
+    parent INT NOT NULL,                -- Pointer to the parent referredby id
+    name TINYTEXT NOT NULL,             -- Name
+    PRIMARY KEY (id),
+    INDEX(parent)
+);
+
+----
+
+-- Referred By to Leads
+CREATE TABLE {prefix}leads_referredby (
+    id INT NOT NULL AUTO_INCREMENT,
+    lead INT NOT NULL,                  -- Reference to lead table
+    referredby INT NOT NULL,            -- Reference to referred by table
+    PRIMARY KEY (id),
+    INDEX(lead),
+    INDEX(referredby)
+);
+
+----
+
+-- Lead Notes
+CREATE TABLE {prefix}lead_notes (
+    id INT NOT NULL AUTO_INCREMENT,
+    lead INT NOT NULL,                  -- Reference to lead table
+    created DATETIME NOT NULL,          -- Created Timestamp
+    updated DATETIME NOT NULL,          -- Updated Timestamp
+    notes TEXT,                         -- Note Entry
+    PRIMARY KEY (id),
+    INDEX(lead)
+);
+
+----
+
+-- Lead Contacts
+CREATE TABLE {prefix}lead_contacts (
+    id INT NOT NULL AUTO_INCREMENT,
+    lead INT NOT NULL,                  -- Reference to lead table
+    updated DATETIME NOT NULL,          -- Updated Timestamp
+    name TINYTEXT,                      -- Name of Contact
+    email TINYTEXT,                     -- Email of Contact
+    phone TINYTEXT,                     -- Phone of Contact
+    PRIMARY KEY (id),
+    INDEX(lead)
+);
+
+----
+
+-- Lead Searches
+CREATE TABLE {prefix}searches (
+  id INT NOT NULL AUTO_INCREMENT,
+  user_id INT NOT NULL,                 -- The wordpress user id
+  updated DATETIME NOT NULL,            -- Last Update Date Time
+  title TINYTEXT NULL,                  -- Title for this search configuration
+  search TEXT NULL,                     -- Serialized array of search parameters
+  PRIMARY KEY (id)
+);
index e102a64..078f484 100644 (file)
@@ -28,5 +28,6 @@
 $glmMembersTravelDbVersions = array(
     '0.0.1' => array('version' => '0.0.1', 'tables' => 4, 'date' => '05/18/18'),
     '0.0.2' => array('version' => '0.0.2', 'tables' => 5, 'date' => '05/23/18'),
+    '0.0.3' => array('version' => '0.0.3', 'tables' => 6, 'date' => '05/31/18'),
 );
 
diff --git a/setup/databaseScripts/update_database_V0.0.3.sql b/setup/databaseScripts/update_database_V0.0.3.sql
new file mode 100644 (file)
index 0000000..170d19e
--- /dev/null
@@ -0,0 +1,17 @@
+-- Gaslight Media Members Database  - Events Add-On
+-- File Created: 05/31/2018
+-- Database Version: 0.0.3
+-- 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 dashes
+
+-- Lead Searches
+CREATE TABLE {prefix}searches (
+  id INT NOT NULL AUTO_INCREMENT,
+  user_id INT NOT NULL,                 -- The wordpress user id
+  updated DATETIME NOT NULL,            -- Last Update Date Time
+  title TINYTEXT NULL,                  -- Title for this search configuration
+  search TEXT NULL,                     -- Serialized array of search parameters
+  PRIMARY KEY (id)
+);
index 6090391..32440aa 100644 (file)
@@ -62,8 +62,10 @@ $glmMembersTravelAddOnValidActions = array(
         'ajax' => array(
             'travelContacts'   => GLM_MEMBERS_TRAVEL_PLUGIN_SLUG,
             'travelReferredby' => GLM_MEMBERS_TRAVEL_PLUGIN_SLUG,
-            'travelSearch'      => GLM_MEMBERS_TRAVEL_PLUGIN_SLUG,
+            'travelSearch'     => GLM_MEMBERS_TRAVEL_PLUGIN_SLUG,
             'travelNotes'      => GLM_MEMBERS_TRAVEL_PLUGIN_SLUG,
+            'leadCsvExport'   => GLM_MEMBERS_TRAVEL_PLUGIN_SLUG,
+            'leadsPdfExport'   => GLM_MEMBERS_TRAVEL_PLUGIN_SLUG,
         ),
         'settings' => array(
             'referredBy' => GLM_MEMBERS_TRAVEL_PLUGIN_SLUG,
index 4533331..1c32393 100644 (file)
                     </td>
                 </tr>
 
+                <tr>
+                    <td {if $lead.fieldRequired.mail_ok}class="glm-required"{/if}>Mail Ok:</td>
+                    <td {if $lead.fieldFail.mail_ok}class="glm-form-bad-input" data-tabid="glm-travel-mail_ok"{/if}>
+                        <input type="checkbox" name="mail_ok" {if $lead.fieldData.mail_ok.value}checked{/if} />
+                        {if $lead.fieldFail.mail_ok}<p>{$lead.fieldFail.mail_ok}</p>{/if}
+                    </td>
+                </tr>
+
                 <tr>
                     <td colspan="2">
                         <input class="button" type="submit" value="Save" >
index 7ba1336..5912670 100644 (file)
@@ -1,38 +1,48 @@
-<div id="travel-admin">
+<div class="clearfix">
     <form id="file_export" action="{$thisUrl}">
         <input type="hidden" name="page" value="{$thisPage}" />
         <input type="hidden" name="glm_action" value="members" />
         <input type="hidden" name="search" value="1" />
-        <fieldset class="clearfix">
+        <fieldset>
             <legend>Search for Group Tour Leads</legend>
-            <div class="field-container">
-                <label>Company</label>
-                <input id="company" name="company"{if isset($smarty.request.company)} value="{$smarty.request.company}"{/if} />
+            <div class="row-container">
+                <div class="field-container">
+                    <label>Company</label>
+                    <input id="company" name="company"{if isset($search_params.company)} value="{$search_params.company}"{/if} />
+                </div>
+                <div class="field-container">
+                    <label>Contact</label>
+                    <input id="contact" name="contact"{if isset($search_params.contact)} value="{$search_params.contact}"{/if} />
+                </div>
             </div>
-            <div class="field-container">
-                <label>Contact</label>
-                <input id="contact" name="contact"{if isset($smarty.request.contact)} value="{$smarty.request.contact}"{/if} />
+            <div class="row-container">
+                <h3>Date Range</h3>
+                <div class="field-container">
+                    <label>From</label>
+                    <input class="datepicker" name="from_date"{if isset($search_params.from_date)} value="{$search_params.from_date}"{/if} required />
+                </div>
+                <div class="field-container">
+                    <label>To</label>
+                    <input class="datepicker" name="to_date"{if isset($search_params.to_date)} value="{$search_params.to_date}"{/if} required />
+                </div>
             </div>
-            <h3>Date Range</h3>
-            <div class="field-container">
-                <label>From</label>
-                <input class="datepicker" name="from_date" />
+            <div class="row-container">
+                <h3><div id="locTogParent">Locations</div></h3>
+                <div class="locTog" style="display: none;">
+                    {foreach $states as $state_abbr => $state_name}
+                        <label class="glmCheckBox">
+                            <input
+                            type="checkbox"
+                            name="state[]"
+                            value="{$state_abbr}"
+                            {if isset($smarty.request.state) && in_array($state_abbr, $smarty.request.state)}checked{/if}>{$state_name}
+                        </label>
+                    {/foreach}
+                </div>
+                <div class="field-container">
+                    <input type="submit" value="Search" />
+                </div>
             </div>
-            <div class="field-container">
-                <label>To</label>
-                <input class="datepicker" name="from_date" />
-            </div>
-            <h3>Locations</h3>
-            <div class="field-container">
-                states
-                <br />
-                <br />
-                <br />
-                <br />
-                <br />
-            </div>
-            <input type="submit" value="Search" />
-                <br />
         </fieldset>
     </form>
 </div>
@@ -40,5 +50,8 @@
 <script>
 jQuery(function($){
     $('.datepicker').datepicker();
+    $('#locTogParent').click(function(){
+        $('div.locTog').toggle();
+    });
 });
 </script>
index 74d4de1..08805d2 100644 (file)
@@ -1,23 +1,41 @@
 {include file='admin/travel/header.html'}
 
+
 {include file='admin/travel/memberSearchForm.html'}
 
-{if $lead}
-    <form action="{$thisUrl}">
-        <input type="hidden" name="page" value="{$thisPage}" />
-        <input type="hidden" name="glm_action" value="members" />
-        <input type="hidden" name="prevStart" value="{$prevStart}">
-        <input type="hidden" name="nextStart" value="{$nextStart}">
-        <input type="hidden" name="limit" value="{$limit}">
-    <br clear="all">
-    <p><b>Total found:</b> {$leadCount}&nbsp;&nbsp;</p>
-    {if $paging}
-        <input type="hidden" name="search" value="1">
+<div id="travel-admin2">
+{if $lead && $searching}
+
+    <form action="{$ajaxUrl}">
+        <input type="hidden" name="action" value="glm_members_admin_ajax" />
+        <input type="hidden" name="glm_action" value="leadPdfExport" />
         {if isset($smarty.request.company)}<input type="hidden" name="company" value="{$smarty.request.company}">{/if}
         {if isset($smarty.request.contact)}<input type="hidden" name="contact" value="{$smarty.request.contact}">{/if}
-        <input type="Submit" name="pageSelect" value="Previous {$limit} Leads" class="button button-secondary glm-button"{if !$prevStart} disabled{/if}>
-        <input type="Submit" name="pageSelect" value="Next {$limit} Leads" class="button button-secondary glm-button"{if !$nextStart} disabled{/if}>
-    {/if}
+        {if isset($smarty.request.from_date)}<input type="hidden" name="from_date" value="{$smarty.request.from_date}">{/if}
+        {if isset($smarty.request.to_date)}<input type="hidden" name="to_date" value="{$smarty.request.to_date}">{/if}
+        {if $smarty.request.state}
+            {foreach $smarty.request.state as $state}
+                <input type="hidden" name="state[]" value="{$state}">
+            {/foreach}
+        {/if}
+        <input type="submit" value="Download all in PDF file">
+    </form>
+    <form action="{$ajaxUrl}">
+        <input type="hidden" name="action" value="glm_members_admin_ajax" />
+        <input type="hidden" name="glm_action" value="leadCsvExport" />
+        {if isset($smarty.request.company)}<input type="hidden" name="company" value="{$smarty.request.company}">{/if}
+        {if isset($smarty.request.contact)}<input type="hidden" name="contact" value="{$smarty.request.contact}">{/if}
+        {if isset($smarty.request.from_date)}<input type="hidden" name="from_date" value="{$smarty.request.from_date}">{/if}
+        {if isset($smarty.request.to_date)}<input type="hidden" name="to_date" value="{$smarty.request.to_date}">{/if}
+        {if $smarty.request.state}
+            {foreach $smarty.request.state as $state}
+                <input type="hidden" name="state[]" value="{$state}">
+            {/foreach}
+        {/if}
+        <input type="submit" value="Download all in CSV file">
+    </form>
+
+    <p><b>Total found:</b> {$leadCount}&nbsp;&nbsp;</p>
 
     <table id="dataGrid" class="dataGrid">
         <thead>
@@ -26,6 +44,8 @@
                 <th> First Name </th>
                 <th> Last Name </th>
                 <th> Updated </th>
+                <th> PDF </th>
+                <th> CSV </th>
             </tr>
         </thead>
         <tbody>
                 <td> {$e.fname} </td>
                 <td> {$e.lname} </td>
                 <td> {$e.updated.datetime} </td>
+                <td>
+                    <a href="{$ajaxUrl}?action=glm_members_admin_ajax&glm_action=leadCsvExport&lead_id={$e.id}">
+                        <img src="{$assetsUrl}/pdf.png">
+                    </a>
+                </td>
+                <td>
+                    <a href="{$ajaxUrl}?action=glm_members_admin_ajax&glm_action=leadCsvExport&lead_id={$e.id}">
+                        <img src="{$assetsUrl}/csv.png">
+                    </a>
+                </td>
             </tr>
             {/foreach}
         </tbody>
     </table>
 
-        {if $paging}
-            <input type="Submit" name="pageSelect" value="Previous {$limit} {$terms.term_member_plur_cap}" class="button button-secondary glm-button"{if !$prevStart} disabled{/if}>
-            <input type="Submit" name="pageSelect" value="Next {$limit} {$terms.term_member_plur_cap}" class="button button-secondary glm-button"{if !$nextStart} disabled{/if}>
-        {/if}
-    </form>
 {else}
-    No search results!
+    <table>
+        <tr>
+            <td>
+                {if $searching}
+                    No search results!
+                {/if}
+                &nbsp;
+            </td>
+        </tr>
+    </table>
 {/if}
 
+</div>
+
 {include file='admin/travel/footer.html'}