Pushing new recurrence times generation code and associated tests
authorChuck Scott <cscott@gaslightmedia.com>
Mon, 29 Feb 2016 18:14:28 +0000 (13:14 -0500)
committerChuck Scott <cscott@gaslightmedia.com>
Mon, 29 Feb 2016 18:14:28 +0000 (13:14 -0500)
13 files changed:
classes/data/dataManagement.php [new file with mode: 0644]
classes/data/dataRecurrences.php
classes/data/dataTimes.php
index.php
models/admin/management/events.php [new file with mode: 0644]
setup/adminTabs.php
setup/databaseScripts/create_database_V0.0.1.sql [deleted file]
setup/databaseScripts/create_database_V0.0.2.sql [new file with mode: 0644]
setup/databaseScripts/dbVersions.php
setup/databaseScripts/update_database_V0.0.2.php [new file with mode: 0644]
setup/databaseScripts/update_database_V0.0.2.sql [new file with mode: 0644]
setup/validActions.php
views/admin/management/events.html [new file with mode: 0644]

diff --git a/classes/data/dataManagement.php b/classes/data/dataManagement.php
new file mode 100644 (file)
index 0000000..ffea990
--- /dev/null
@@ -0,0 +1,158 @@
+<?php
+/**
+ * GLM Member-DB WordPress Add-On Plugin
+ * Data Class Management
+ *
+ * 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 $
+ */
+
+/**
+ * GlmDataEvent 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 GlmDataEventsManagement 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;
+    /**
+     * MemberInfo DB object
+     *
+     * @var $MemberInfo
+     * @access public
+     */
+    public $MemberInfo;
+
+    /**
+     * 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_EVENTS_PLUGIN_DB_PREFIX . 'management';
+
+        /*
+         * Table Data Fields
+         */
+
+        $this->fields = array (
+
+            'id' => array (
+                'field' => 'id',
+                'type' => 'integer',
+                'view_only' => true,
+                'use' => 'a'
+            ),
+
+           // Canonical Page Slug
+            'canonical_event_page' => array (
+                'field' => 'canonical_event_page',
+                '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;
+    }
+
+}
+
+?>
index 11e2baa..1a902b1 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 // Member Info Data required
-require_once(GLM_MEMBERS_PLUGIN_CLASS_PATH.'/data/dataMemberInfo.php');
+require_once GLM_MEMBERS_PLUGIN_CLASS_PATH.'/data/dataMemberInfo.php';
 
 /**
  * GlmDataEvent class
@@ -147,6 +147,20 @@ class GlmDataEventsRecurrences extends GlmDataAbstract
                 'use' => 'a'
             ),
 
+            // From Date - Event Times are created starting at this date
+            'from_date' => array (
+                'field' => 'from_date',
+                'type' => 'date',
+                'use' => 'a'
+            ),
+
+            // To Date - Event Times are created ending at this date
+            'to_date' => array (
+                'field' => 'to_date',
+                'type' => 'date',
+                'use' => 'a'
+            ),
+
             // All Day Flag
             'all_day' => array (
                 'field' => 'all_day',
@@ -186,11 +200,19 @@ class GlmDataEventsRecurrences extends GlmDataAbstract
             'day_of_month' => array(
                     'field'    => 'day_of_month',
                     'type'     => 'bitmap',
-                    'bitmap'    => $this->config['day'],
+                    'bitmap'    => $this->config['day_of_month'],
                     'default'  => 0, // no day selected
                     'use'      => 'a'
             ),
 
+            // Last Day of Month
+            'last_day_of_month' => array (
+                'field' => 'last_day_of_month',
+                'type' => 'checkbox',
+                'default' => false,
+                'use' => 'a'
+            ),
+
             /*
              * Following included for future Holiday feature
              */
@@ -232,6 +254,199 @@ class GlmDataEventsRecurrences extends GlmDataAbstract
         return $r;
     }
 
+    /*
+     * Calculate and create all entries for the times table from recurrence data.
+     *
+     * @param integer $recurID ID of the event recurrence record
+     * @param boolean $deleteCustomEvents Flag to ask for all custom event data
+     *     for the event to also be deleted
+     *
+     * @return object Class object
+     *
+     */
+    public function deleteTimeEntriesForRecurrance($recurID, $deleteCustomEventData = false)
+    {
+
+        // Force ID to be numeric
+        $recurID = $recurID - 0;
+
+        // If ID is sane
+        if ($recurID > 0) {
+
+            $where = '';
+
+            // If delete custom events is requested
+            if ($deleteCustomEventData) {
+
+                // Get ID of event from recurrence and delete any custom events
+                $recurData = $this->getEntry($recurID);
+                if ($recurData && $recurData['event'] > 0) {
+                    $this->wpdb->query("
+                        DELETE FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX ."events
+                         WHERE root_event = $recurID
+                    ;");
+                }
+
+            // Otherwise don't delete times for the custom events
+            } else {
+                $where = "AND (custom_event IS NULL OR custom_event = 0)";
+            }
+
+            $this->wpdb->query("
+                DELETE FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX ."times
+                 WHERE recur_id = $recurID
+                       $where
+            ;");
+
+        }
+    }
+
+    /*
+     * Calculate and create all entries for the times table from recurrence data.
+     *
+     * @param array $recurID ID of recurrence entry
+     * @param boolean $replace Flag to delete all event times for this recurrence first (default is TRUE!)
+     * @param boolean $deleteCustomEventData Delete all existing Custom event data first
+     *
+     * @return object Class object
+     *
+     */
+    public function createRecurrenceTimesEntries($recurID, $replaceEventTimes = true, $deleteCustomEventData = false)
+    {
+
+        $times = false;
+        $dates = array();
+
+        // Make sure recurrence ID is a number
+        $recurID = ($recurID - 0);
+        if ($recurID <= 0) {
+            return false;
+        }
+
+        // Get recurrence data
+        $recurData = $this->getEntry($recurID);
+        if (!$recurData) {
+            return false;
+        }
+
+        // Overall range to scan for event times
+        $from = new DateTime($recurData['from_date']['date']);
+        $to = new DateTime($recurData['to_date']['date']);
+
+        // Calculate interval for single event
+        $start = new DateTime($recurData['start_time']['datetime']);
+        $end = new DateTime($recurData['end_time']['datetime']);
+        $length = $start->diff($end);
+
+        // Determine years for scan
+        $fromYear = $from->format('Y');
+        $toYear = $to->format('Y');
+
+        // For each year in recurrence range
+        for ($year = $fromYear ; $year <= $toYear ; $year++ ) {
+
+            // For each Month selected
+            foreach ($recurData['month_of_year']['names'] as $km=>$month) {
+
+                // For each week selected
+                foreach ($recurData['week_of_month']['names'] as $kw=>$week) {
+
+                    // For each day selected
+                    foreach ($recurData['day_of_week']['names'] as $kd=>$day) {
+
+                        $dates[] = new DateTime("$week $day of $month $year");
+
+                    } // Day of Week
+
+                } // Week of Month
+
+                // For each specifi days of the month
+                foreach ($recurData['day_of_month']['names'] as $kdom=>$dom) {
+
+                    $dates[] = new DateTime("$month $dom $year");
+
+                }
+
+                // If last day of month is selected
+                if ($recurData['last_day_of_month']['value']) {
+                    $dates[] = new DateTime("last day of $month $year");
+                }
+
+
+            } // Month of Year
+
+        } // Year
+
+
+        // Create From and to timestamp for comparison
+        $fromTime = $from->getTimestamp();
+        $toTime = $to->getTimestamp();
+
+        // Check for $replace, if so delete all existing entries and custom events
+        if ($replaceEventTimes) {
+            $this->deleteTimeEntriesForRecurrance($recurData['id'], $deleteCustomEventData);
+        }
+
+        // If there's any dates generated
+        if (count($dates) > 0) {
+
+            // For each date generated - create a times entry
+            foreach ($dates as $k=>$v) {
+
+                $thisDate = $v->getTimestamp();
+
+                // If date is within from and to range (we didn't check this above)
+                if ($thisDate >= $fromTime && $thisDate <= $toTime ) {
+
+                    // Create text start date and time of this instance
+                    $thisStartTime = $v->format('Y/m/d').date(' H:i:s', $recurData['start_time']['timestamp']);
+                    $tst = new DateTime($thisStartTime);
+
+                    // Create text end date and time of this instance
+                    $tet =  $tst;
+                    $tet->add($length);
+                    $thisEndTime = $tet->format('Y/m/d H:i:s');
+
+                    // Store this event time
+                    $this->wpdb->insert(
+                        GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX . 'times',
+                        array(
+                            'event' => $recurData['event'],
+                            'custom_event' => 0,
+                            'recur_id' => $recurID,
+                            'active' => true,
+                            'start_time' => $thisStartTime,
+                            'end_time' => $thisEndTime,
+                            'all_day' => $recurData['all_day']['value']
+                        ),
+                        array(
+                            '%d',
+                            '%d',
+                            '%d',
+                            '%d',
+                            '%s',
+                            '%s',
+                            '%d'
+                        )
+                    );
+
+                }
+
+            }
+
+        }
+
+        // Load all times stored for this recurrence
+        require_once GLM_MEMBERS_EVENTS_PLUGIN_CLASS_PATH.'/data/dataTimes.php';
+        $Times = new GlmDataEventsTimes($this->wpdb, $this->config);
+        $timesData = $Times->getList("T.recur_id = $recurID");
+
+        return $timesData;
+    }
+
+
+
+
 }
 
 ?>
index 68be173..ee1b284 100644 (file)
@@ -141,6 +141,14 @@ class GlmDataEventsTimes extends GlmDataAbstract
                 'use' => 'glei'
             ),
 
+            // Recurrence ID
+            'recur_id' => array(
+                'field' => 'recur_id',
+                'type' => 'integer',
+                'required' => true,
+                'use' => 'glei'
+            ),
+
             // Active Flag
             'active' => array (
                 'field' => 'active',
index 3da07b6..822fd64 100644 (file)
--- a/index.php
+++ b/index.php
@@ -39,7 +39,7 @@
  *  version from this plugin.
  */
 define('GLM_MEMBERS_EVENTS_PLUGIN_VERSION', '0.0.1');
-define('GLM_MEMBERS_EVENTS_PLUGIN_DB_VERSION', '0.0.1');
+define('GLM_MEMBERS_EVENTS_PLUGIN_DB_VERSION', '0.0.2');
 
 // This is the minimum version of the GLM Members DB plugin require for this plugin.
 define('GLM_MEMBERS_EVENTS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION', '1.0.58');
diff --git a/models/admin/management/events.php b/models/admin/management/events.php
new file mode 100644 (file)
index 0000000..6212886
--- /dev/null
@@ -0,0 +1,284 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * GLM Members DB - Events Add-on - Management Events Tab
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  events.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+// Load Management Events data abstract
+require_once GLM_MEMBERS_EVENTS_PLUGIN_CLASS_PATH.'/data/dataManagement.php';
+
+/**
+ * GlmMembersAdmin_management_packaging
+ *
+ * PHP version 5
+ *
+ * @category Model
+ * @package GLM Member DB
+ * @author  Chuck Scott <cscott@gaslightmedia.com>
+ * @license http://www.gaslightmedia.com Gaslightmedia
+ *          @release SVN: $Id: packaging.php,v 1.0 2011/01/25 19:31:47 cscott
+ *          Exp $
+ */
+class GlmMembersAdmin_management_events extends GlmDataEventsManagement
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * This contructor performs the work for this model. This model returns
+     * an array containing the following.
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     * @wpdb object WordPress database object
+     *
+     * @return array Array containing status, suggested view, and any data
+     */
+    public function __construct ($wpdb, $config)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        // Save plugin configuration object
+        $this->config = $config;
+
+        // Run constructor for members data class
+        parent::__construct(false, false);
+
+    }
+
+    public function modelAction($actionData = false)
+    {
+
+        $option = false;
+        $testResult = false;
+        $settingsUpdated = false;
+        $settingsUpdateError = false;
+        $eventsSettings = false;
+
+        if (isset($_REQUEST['option'])) {
+            $option = $_REQUEST['option'];
+        }
+
+        switch ($option) {
+
+            case 'tests':
+
+                $test = false;
+                if (isset($_REQUEST['test'])) {
+                    $test = $_REQUEST['test'];
+                }
+
+                switch ($test) {
+
+                    case 'recurrence':
+
+                        $testResult = $this->testRecurrence();
+
+                        break;
+
+                    default:
+                        break;
+                }
+
+                break;
+
+            case 'settings':
+            default:
+
+                // Make sure option is set if default
+                $option = 'settings';
+
+                // Determine if current user can edit configurations
+                if (!current_user_can('glm_members_management')) {
+                    return array(
+                        'status' => false,
+                        'menuItemRedirect' => 'error',
+                        'modelRedirect' => 'index',
+                        'view' => 'admin/error/index.html',
+                        'data' => array(
+                                'reason' => 'User does not have rights to make configuration changes.'
+                        )
+                    );
+                }
+
+                // Check for submission option
+                $option2 = '';
+                if (isset($_REQUEST['option2'])) {
+                    $option2 = $_REQUEST['option2'];
+                }
+
+                switch($option2) {
+
+                    // Update the settings and redisplay the form
+                    case 'submit':
+
+                        // Update the event management settings
+                        $eventsSettings = $this->updateEntry(1);
+                        if ($eventsSettings['status']) {
+                            $settingsUpdated = true;
+                        } else {
+                            $settingsUpdateError = true;
+                        }
+
+                        break;
+
+                    // Default is to get the current settings and display the form
+                    default:
+
+                        // Try to get the first (should be only) entry for general settings.
+                        $eventsSettings = $this->editEntry(1);
+
+                        if ($eventsSettings === false) {
+
+                            if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG) {
+                                glmMembersAdmin::addNotice("<b>&nbsp;&nbsp;/models/admin/management/events.php: Unable to load events management settings.", 'Alert');
+                            }
+
+                        }
+
+                        break;
+
+                }
+
+                break;
+
+        }
+
+        // Compile template data
+        $templateData = array(
+            'option' => $option,
+            'testResult' => $testResult,
+            'settingsUpdated' => $settingsUpdated,
+            'settingsUpdateError' => $settingsUpdateError,
+            'eventsSettings' => $eventsSettings
+        );
+
+        // Return status, suggested view, and data to controller
+        return array(
+            'status' => true,
+            'menuItemRedirect' => false,
+            'modelRedirect' => false,
+            'view' => 'admin/management/events.html',
+            'data' => $templateData
+        );
+
+
+    }
+
+    /*
+     * Test Recurrance Calculation of Dates
+     *
+     * @return test Text of test results
+     */
+    public function testRecurrence()
+    {
+
+        $res = '';
+
+        // Load recurrences class
+        require_once GLM_MEMBERS_EVENTS_PLUGIN_CLASS_PATH.'/data/dataRecurrences.php';
+        $Recurrences = new GlmDataEventsRecurrences($this->wpdb, $this->config);
+
+        // Create sample recurrence entry
+        $start_time = '2016/2/27 08:00:00';
+        $res .= "First event start date/time: $start_time<br>";
+        $end_time = '2016/2/28 17:00:00';
+        $res .= "First event end date/time: $end_time<br>";
+        $from_date = '2016/2/1';
+        $res .= "From date: $from_date<br>";
+        $to_date = '2017/3/31';
+        $res .= "To date: $to_date<br>";
+
+        $this->wpdb->insert(
+            GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX . 'recurrences',
+            array(
+                'event' => 999999999,
+                'start_time' => $start_time,
+                'end_time' => $end_time,
+                'from_date' => $from_date,
+                'to_date' => $to_date,
+                'all_day' => false,
+                'month_of_year' =>
+                    pow(2, $this->config['month_bit']['January']) +
+                    pow(2, $this->config['month_bit']['June']),
+                'week_of_month' =>
+                    pow(2, $this->config['week_bit']['Third']) +
+                    pow(2, $this->config['week_bit']['First']),
+                'day_of_week' =>
+                    pow(2, $this->config['day_bit']['Wednesday']) +
+                    pow(2, $this->config['day_bit']['Friday']),
+                'day_of_month' =>
+                    pow(2, 1) + pow(2, 13) + pow(2, 26) + pow(2, 30),
+                'last_day_of_month' => true,
+                'holiday' => 0,
+                'holiday_offset' => 0
+            ),
+            array(
+                '%d',
+                '%s',
+                '%s',
+                '%s',
+                '%s',
+                '%d',
+                '%d',
+                '%d',
+                '%d',
+                '%d',
+                '%d',
+                '%d',
+                '%d'
+            )
+        );
+        $recurID = $this->wpdb->insert_id;
+        if (!$recurID) {
+            return 'Error inserting recurrence entry!';
+        }
+
+        // Run recurrence time function
+        $Recurrences->optionIncludeSelectListData = false;
+        $times = $Recurrences->createRecurrenceTimesEntries($recurID, true, true);
+
+        // Delete test recurrence
+//        $this->wpdb->delete( GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX . 'recurrences', array( 'ID' => $recurID ) );
+
+        $res .= "<h3>Times Entries Generated</h3><pre>".print_r($times,1)."</pre>";
+
+        return $res;
+
+    }
+
+}
+
+?>
\ No newline at end of file
index e90461d..8dafef1 100644 (file)
@@ -54,7 +54,7 @@ add_filter('glm-member-db-add-tab-for-member',
                 'menu' => 'member',
                 'action' => 'events'
             ),
-          
+
         );
         $addOnTabs = array_merge($addOnTabs, $newTabs);
         return $addOnTabs;
@@ -69,7 +69,7 @@ add_filter('glm-member-db-add-tab-for-events',
                 'menu' => 'events',
                 'action' => 'add'
             ),
-          
+
         );
         $addOnTabs = array_merge($addOnTabs, $newTabs);
         return $addOnTabs;
@@ -84,9 +84,26 @@ add_filter('glm-member-db-add-tab-for-events',
                 'menu' => 'events',
                 'action' => 'categories'
             ),
-          
+
         );
         $addOnTabs = array_merge($addOnTabs, $newTabs);
         return $addOnTabs;
     }
-);
\ No newline at end of file
+);
+
+if (apply_filters('glm_members_permit_admin_members_events_tab', true)) {
+    add_filter('glm-member-db-add-tab-for-management',
+        function($addOnTabs) {
+            $newTabs = array(
+                array(
+                    'text' => 'Events',
+                    'menu' => 'management',
+                    'action' => 'events'
+                )
+            );
+            $addOnTabs = array_merge($addOnTabs, $newTabs);
+            return $addOnTabs;
+        }
+    );
+}
+
diff --git a/setup/databaseScripts/create_database_V0.0.1.sql b/setup/databaseScripts/create_database_V0.0.1.sql
deleted file mode 100644 (file)
index 763f970..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
--- Gaslight Media Members Database - Events Add-On 
--- File Created: 12/02/15 15:27:15
--- Database Version: 0.0.1
--- Database Creation Script
--- 
--- This file is called to create a new set of tables for this
--- add-on for the most receint database version for this add-on.
--- 
--- There should only be one such file in this directory
---
--- To permit each query below to be executed separately,
--- all queries must be separated by a line with four dashes
-
--- Categories - Categories for events
-CREATE TABLE {prefix}categories (
-  id INT NOT NULL AUTO_INCREMENT,
-  name TINYTEXT NULL,                                   -- Name of event category
-  descr TINYTEXT NULL,                                  -- Description of this category
-  parent INT NULL,                                      -- Parent category, null or 0 if this is a top level category
-  PRIMARY KEY (id),
-  INDEX(parent)
-);
-
-----
-
--- Event-Category - Categories for specific event records
-CREATE TABLE {prefix}event_categories (
-  id INT NOT NULL AUTO_INCREMENT,
-  event INT NULL,                                       -- Pointer to the event
-  category INT NULL,                                    -- Pointer to the category
-  PRIMARY KEY (id),
-  INDEX(event),
-  INDEX(category)
-);
-
-----
-
--- Event Recurrence - Defines how an event recurs
-CREATE TABLE {prefix}recurrences (
-  id INT NOT NULL AUTO_INCREMENT,
-  event INTEGER NULL,                                   -- Pointer to event
-  start_time DATETIME NULL,                             -- Start of first occurance (date and time)
-  end_time DATETIME NULL,                               -- End of first occurance (date and time)
-  all_day BOOLEAN NULL,                                 -- Flag indicating if this is an all-day event (inforational only)
-  month_of_year SMALLINT UNSIGNED NULL,                 -- Month of year (bitmap)
-  week_of_month TINYINT UNSIGNED NULL,                  -- Week of the month (bitmap)
-  day_of_week TINYINT UNSIGNED NULL,                    -- Day of the week (bitmap)
-  day_of_month INTEGER UNSIGNED NULL,                   -- Day of the month (bitmap)
-  holiday INT NULL,                                     -- Pointer to holidays list (for future development)
-  holiday_offset TINYINT,                               -- Offset from holiday (from -128 to +127 days)
-  PRIMARY KEY (id),
-  INDEX(event)
-);
-
-----
-
--- Times - List of actual event times for single and recurring events
-CREATE TABLE {prefix}times (
-  id INT NOT NULL AUTO_INCREMENT,
-  event INT NULL,                                       -- Pointer to the primary record for the event
-  custom_event INT NULL,                                -- Pointer to a customized copy of the event record (if set)
-  active BOOLEAN NULL,                                  -- Active flag - normally set but used to temporarily dissable a specific date
-  start_time DATETIME NULL,                             -- Date and time event starts
-  end_time DATETIME NULL,                               -- Date and time event ends
-  all_day BOOLEAN NULL,                                 -- All Day flag
-  PRIMARY KEY (id),
-  INDEX(event),
-  INDEX(start_time),
-  INDEX(end_time)
-);
-
-----
-
--- Locations - Locations for event - If there's no location pointing to an event try to use the referernced entity in events table
-CREATE TABLE {prefix}locations (
-  id INT NOT NULL AUTO_INCREMENT,
-  event INT NULL,                                       -- Pointer to the primary or custom event record
-  name TINYTEXT NULL,                                   -- Name of location
-  address TINYTEXT NULL,                                -- Street Address 
-  city INT NULL,                                        -- Pointer to city - references main plugin city table
-  state TINYTEXT NULL,                                  -- Two character state abreviation
-  zip TINYTEXT NULL,                                    -- ZIP/Postal code
-  country TINYTEXT NULL,                                -- Country Code
-  lat FLOAT NULL,                                       -- Latitude of location
-  lon FLOAT NULL,                                       -- Longitude of location
-  region INT NULL,                                      -- Pointer to Region - references main plugin region table
-  phone TINYTEXT NULL,                                  -- Location Phone #
-  url TINYTEXT NULL,                                    -- Location URL
-  email TINYTEXT NULL,                                  -- Location E-Mail Address
-  contact_addon_id INT NULL,                            -- ID of Contact from contact add-on (optional and if available)
-  contact_fname TINYTEXT NULL,                          -- Contact first name for this location (optional)
-  contact_lname TINYTEXT NULL,                          -- Contact last name for this location (optional)
-  contact_phone TINYTEXT NULL,                          -- Contact phone for this location (optional)
-  contact_email TINYTEXT NULL,                          -- Contact E-Mail address (optional)
-  PRIMARY KEY (id)
-);
-
-----
-
--- Events - Base event information - May also be entries here referenced by the "times" table for a custom date.
-CREATE TABLE {prefix}events (
-  id INT NOT NULL AUTO_INCREMENT,
-  status INT NULL,                                      -- Status for this event, see config['status']
-  custom_time INT NULL,                                 -- If this is a custom record for a specific instance (date) this points to that times table entry  
-  root_event INT NULL,                                  -- Root event pointer if this is a custom record for a specific instance (date) (if custom_time is set)
-  created DATETIME NULL,                                -- Date/Time event was created or date custom event record was created if custom record
-  updated DATETIME NULL,                                -- Date/Time this event record was last updated
-  approved DATETIME NULL,                               -- Date/Ttime this event record was approved
-  ref_type INT NULL,                                    -- Type of entity this contact is associated with - See config['ref_type']                        
-  ref_dest INT NULL,                                    -- Pointer to the specific entity of ref_type this contact is associated with
-  hide_address BOOLEAN NULL,                            -- Option to hide address on front-end
-  featured BOOLEAN NULL,                                -- Option to mark as featured event
-  slideshow BOOLEAN NULL,                               -- Option to mark for use in slide show
-  major BOOLEAN NULL,                                   -- Option to mark as a major event
-  name TINYTEXT NULL,                                   -- Name of this event
-  header TINYTEXT NULL,                                 -- Header text for front-end display
-  intro TINYTEXT NULL,                                  -- Intro text for front-end display
-  descr TEXT NULL,                                      -- Full description text
-  image TINYTEXT NULL,                                  -- Image file name
-  url TINYTEXT NULL,                                    -- Event URL
-  cost TINYTEXT NULL,                                   -- Description of event cost
-  notes TEXT NULL,                                      -- Internal notes for this event
-  PRIMARY KEY (id),
-  INDEX(custom_time),
-  INDEX(root_event),
-  INDEX(ref_type),
-  INDEX(ref_dest),
-  INDEX(featured),
-  INDEX(slideshow),
-  INDEX(major)
-);
diff --git a/setup/databaseScripts/create_database_V0.0.2.sql b/setup/databaseScripts/create_database_V0.0.2.sql
new file mode 100644 (file)
index 0000000..0f82524
--- /dev/null
@@ -0,0 +1,155 @@
+-- Gaslight Media Members Database - Events Add-On 
+-- File Created: 12/02/15 15:27:15
+-- Database Version: 0.0.1
+-- Database Creation Script
+-- 
+-- This file is called to create a new set of tables for this
+-- add-on for the most receint database version for this add-on.
+-- 
+-- There should only be one such file in this directory
+--
+-- To permit each query below to be executed separately,
+-- all queries must be separated by a line with four dashes
+
+-- Categories - Categories for events
+CREATE TABLE {prefix}categories (
+  id INT NOT NULL AUTO_INCREMENT,
+  name TINYTEXT NULL,                                   -- Name of event category
+  descr TINYTEXT NULL,                                  -- Description of this category
+  parent INT NULL,                                      -- Parent category, null or 0 if this is a top level category
+  PRIMARY KEY (id),
+  INDEX(parent)
+);
+
+----
+
+-- Event-Category - Categories for specific event records
+CREATE TABLE {prefix}event_categories (
+  id INT NOT NULL AUTO_INCREMENT,
+  event INT NULL,                                       -- Pointer to the event
+  category INT NULL,                                    -- Pointer to the category
+  PRIMARY KEY (id),
+  INDEX(event),
+  INDEX(category)
+);
+
+----
+
+-- Event Recurrence - Defines how an event recurs
+CREATE TABLE {prefix}recurrences (
+  id INT NOT NULL AUTO_INCREMENT,
+  event INTEGER NULL,                                   -- Pointer to event
+  start_time DATETIME NULL,                             -- Start of first occurance (date and time)
+  end_time DATETIME NULL,                               -- End of first occurance (date and time)
+  from_date DATE NULL,                                  -- From Date for recurrences
+  to_date DATE NULL,                                    -- To Date for recurrences
+  all_day BOOLEAN NULL,                                 -- Flag indicating if this is an all-day event (inforational only)
+  month_of_year SMALLINT UNSIGNED NULL,                 -- Month of year (bitmap)
+  week_of_month TINYINT UNSIGNED NULL,                  -- Week of the month (bitmap)
+  day_of_week TINYINT UNSIGNED NULL,                    -- Day of the week (bitmap)
+  day_of_month INTEGER UNSIGNED NULL,                   -- Day of the month (bitmap)
+  last_day_of_month BOOLEAN NULL,                       -- Last day of the month
+  holiday INT NULL,                                     -- Pointer to holidays list (for future development)
+  holiday_offset TINYINT,                               -- Offset from holiday (from -128 to +127 days)
+  PRIMARY KEY (id),
+  INDEX(event)
+);
+
+----
+
+-- Times - List of actual event times for single and recurring events
+CREATE TABLE {prefix}times (
+  id INT NOT NULL AUTO_INCREMENT,
+  event INT NULL,                                       -- Pointer to the primary record for the event
+  custom_event INT NULL,                                -- Pointer to a customized copy of the event record (if set)
+  recur_id INT NULL,                                    -- Pointer to recurrance entry
+  active BOOLEAN NULL,                                  -- Active flag - normally set but used to temporarily dissable a specific date
+  start_time DATETIME NULL,                             -- Date and time event starts
+  end_time DATETIME NULL,                               -- Date and time event ends
+  all_day BOOLEAN NULL,                                 -- All Day flag
+  PRIMARY KEY (id),
+  INDEX(event),
+  INDEX(start_time),
+  INDEX(end_time)
+);
+
+----
+
+-- Locations - Locations for event - If there's no location pointing to an event try to use the referernced entity in events table
+CREATE TABLE {prefix}locations (
+  id INT NOT NULL AUTO_INCREMENT,
+  event INT NULL,                                       -- Pointer to the primary or custom event record
+  name TINYTEXT NULL,                                   -- Name of location
+  address TINYTEXT NULL,                                -- Street Address 
+  city INT NULL,                                        -- Pointer to city - references main plugin city table
+  state TINYTEXT NULL,                                  -- Two character state abreviation
+  zip TINYTEXT NULL,                                    -- ZIP/Postal code
+  country TINYTEXT NULL,                                -- Country Code
+  lat FLOAT NULL,                                       -- Latitude of location
+  lon FLOAT NULL,                                       -- Longitude of location
+  region INT NULL,                                      -- Pointer to Region - references main plugin region table
+  phone TINYTEXT NULL,                                  -- Location Phone #
+  url TINYTEXT NULL,                                    -- Location URL
+  email TINYTEXT NULL,                                  -- Location E-Mail Address
+  contact_addon_id INT NULL,                            -- ID of Contact from contact add-on (optional and if available)
+  contact_fname TINYTEXT NULL,                          -- Contact first name for this location (optional)
+  contact_lname TINYTEXT NULL,                          -- Contact last name for this location (optional)
+  contact_phone TINYTEXT NULL,                          -- Contact phone for this location (optional)
+  contact_email TINYTEXT NULL,                          -- Contact E-Mail address (optional)
+  PRIMARY KEY (id)
+);
+
+----
+
+-- Events - Base event information - May also be entries here referenced by the "times" table for a custom date.
+CREATE TABLE {prefix}events (
+  id INT NOT NULL AUTO_INCREMENT,
+  status INT NULL,                                      -- Status for this event, see config['status']
+  custom_time INT NULL,                                 -- If this is a custom record for a specific instance (date) this points to that times table entry  
+  root_event INT NULL,                                  -- Root event pointer if this is a custom record for a specific instance (date) (if custom_time is set)
+  created DATETIME NULL,                                -- Date/Time event was created or date custom event record was created if custom record
+  updated DATETIME NULL,                                -- Date/Time this event record was last updated
+  approved DATETIME NULL,                               -- Date/Ttime this event record was approved
+  ref_type INT NULL,                                    -- Type of entity this contact is associated with - See config['ref_type']                        
+  ref_dest INT NULL,                                    -- Pointer to the specific entity of ref_type this contact is associated with
+  hide_address BOOLEAN NULL,                            -- Option to hide address on front-end
+  featured BOOLEAN NULL,                                -- Option to mark as featured event
+  slideshow BOOLEAN NULL,                               -- Option to mark for use in slide show
+  major BOOLEAN NULL,                                   -- Option to mark as a major event
+  name TINYTEXT NULL,                                   -- Name of this event
+  name_slug TINYTEXT NULL,                              -- Slug for this event
+  header TINYTEXT NULL,                                 -- Header text for front-end display
+  intro TINYTEXT NULL,                                  -- Intro text for front-end display
+  descr TEXT NULL,                                      -- Full description text
+  image TINYTEXT NULL,                                  -- Image file name
+  url TINYTEXT NULL,                                    -- Event URL
+  cost TINYTEXT NULL,                                   -- Description of event cost
+  notes TEXT NULL,                                      -- Internal notes for this event
+  PRIMARY KEY (id),
+  INDEX(custom_time),
+  INDEX(root_event),
+  INDEX(ref_type),
+  INDEX(ref_dest),
+  INDEX(featured),
+  INDEX(slideshow),
+  INDEX(major)
+);
+
+----
+
+-- Event Management Settings
+CREATE TABLE {prefix}management (
+  id INT NOT NULL AUTO_INCREMENT,
+  canonical_event_page TINYTEXT NULL,          -- Canonical page slug for event detail
+  PRIMARY KEY (id)
+);
+
+----
+
+-- Set default event management entry
+INSERT INTO {prefix}management
+    ( id, canonical_event_page )
+   VALUES
+    ( 1, 'event-detail' )
+;
+
index 57ac568..919ea67 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 $glmMembersEventsDbVersions = array(
-            '0.0.1' => array('version' => '0.0.1', 'tables' => 6)
+    '0.0.1' => array('version' => '0.0.1', 'tables' => 6),
+    '0.0.2' => array('version' => '0.0.2', 'tables' => 7)
 );
 
diff --git a/setup/databaseScripts/update_database_V0.0.2.php b/setup/databaseScripts/update_database_V0.0.2.php
new file mode 100644 (file)
index 0000000..37c440e
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+/*
+ * Gaslight Media Members Database - Events Add-On
+ *
+ * Database Update Script for version 0.0.2
+ */
+
+// Update event records with name slug for URLs
+$eventRecords = $this->wpdb->get_results('SELECT id, name FROM '.GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX.'events;', ARRAY_A);
+if ($eventRecords && count($eventRecords) > 0) {
+    foreach ($eventRecords as $i) {
+        $slug = sanitize_title($i['name']);
+        $this->wpdb->update(
+                GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX.'events',
+                array(
+                        'name_slug' => $slug
+                ),
+                array( 'id' => $i['id'] ),
+                array( '%s' ),
+                array( '%d')
+        );
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/setup/databaseScripts/update_database_V0.0.2.sql b/setup/databaseScripts/update_database_V0.0.2.sql
new file mode 100644 (file)
index 0000000..5e7a175
--- /dev/null
@@ -0,0 +1,54 @@
+-- Gaslight Media Members Database  - Events Add-On
+-- File Created: 12/09/14 15:27:15
+-- 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
+
+
+-- Event Management Settings
+CREATE TABLE {prefix}management (
+  id INT NOT NULL AUTO_INCREMENT,
+  canonical_event_page TINYTEXT NULL,          -- Canonical page slug for event detail
+  PRIMARY KEY (id)
+);
+
+----
+
+-- Set default event management entry
+INSERT INTO {prefix}management
+    ( id, canonical_event_page )
+   VALUES
+    ( 1, 'event-detail' )
+;
+
+----
+
+-- Add slug to event table
+ALTER TABLE {prefix}events ADD COLUMN name_slug TINYTEXT;
+
+----
+
+-- Add from date to recurrence table
+ALTER TABLE {prefix}recurrences ADD COLUMN from_date DATE;
+
+----
+
+-- Add to date to recurrence table
+ALTER TABLE {prefix}recurrences ADD COLUMN to_date DATE;
+
+----
+
+-- Add to date to recurrence table
+ALTER TABLE {prefix}recurrences ADD COLUMN last_day_of_month BOOLEAN;
+
+----
+
+-- Add to recurrence ID to times table 
+ALTER TABLE {prefix}times ADD COLUMN recur_id INT;
+
+
+
+
+
index 50b75f0..d5638ac 100644 (file)
@@ -43,6 +43,9 @@ $glmMembersEventsAddOnValidActions = array(
             'add' => GLM_MEMBERS_EVENTS_PLUGIN_SLUG,
             'categories' => GLM_MEMBERS_EVENTS_PLUGIN_SLUG
         ),
+        'management' => array(
+            'events' => GLM_MEMBERS_EVENTS_PLUGIN_SLUG
+        )
     ),
     'frontActions' => array(
 /*
diff --git a/views/admin/management/events.html b/views/admin/management/events.html
new file mode 100644 (file)
index 0000000..5326898
--- /dev/null
@@ -0,0 +1,90 @@
+{include file='admin/management/header.html'}
+
+    <h2 class="nav-tab-wrapper" style="margin-bottom: 1em;">
+        <a id="glm-settings" data-show-table="glm-table-settings" class="glm-settings-tab nav-tab{if $option=='settings'} nav-tab-active{/if}">Settings</a>
+        <a id="glm-tests" data-show-table="glm-table-tests" class="glm-settings-tab nav-tab{if $option=='tests'} nav-tab-active{/if}">Tests</a>
+    </h2>
+    
+    <!-- Management Settings -->
+    
+    <table id="glm-table-settings" class="glm-admin-table glm-settings-table{if $option!='settings'} glm-hidden{/if}">
+        <tr>
+            <td colspan="2">
+                {if $settingsUpdated}<h2 class="glm-notice glm-flash-updated glm-right">Settings Updated</h2>{/if}
+                {if $settingsUpdateError}<span class="glm-error glm-flash-updated glm-right">Settings Update Error</span>{/if}
+                <h2>Management Settings</h2>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <form action="{$thisURL}?page={$thisPage}" method="post" enctype="multipart/form-data">
+                    <input type="hidden" name="glm_action" value="events">
+                    <input type="hidden" name="option" value="settings">
+                    <input type="hidden" name="option2" value="submit">
+                    <table class="glm-admin-table">
+                        <tr>
+                            <th {if $eventsSettings.fieldRequired.canonical_event_page}class="glm-required"{/if}>Event Detail Page Permalink Name:</th>
+                            <td {if $eventsSettings.fieldFail.canonical_event_page}class="glm-form-bad-input glm-form-bad-input-misc"{/if}>
+                                <input type="text" name="canonical_event_page" value="{$eventsSettings.fieldData.canonical_event_page}" class="glm-form-text-input-medium">
+                                {if $eventsSettings.fieldFail.canonical_event_page}<p>{$eventsSettings.fieldFail.canonical_event_page}</p>{/if}
+                            </td>
+                        </tr>
+                    </table>
+                    <input type="submit" value="Update Settings" class="button-primary">
+                </form>
+            </td>
+        </tr>
+    </table>
+    
+    <!-- Tests -->
+    
+    <table id="glm-table-tests" class="glm-admin-table glm-settings-table{if $option!='tests'} glm-hidden{/if}">
+  {if $testResult}
+        <tr><td><a href="{$thisURL}?page={$thisPage}&glm_action=events&option=tests">Return to Test List</a></td></tr>
+        <tr>
+            <td colspan="2">
+                {$testResult}
+            </td>
+        </tr>
+  {else}
+        <tr>
+            <td colspan="2">
+                <ul>
+                    <li><a href="{$thisURL}?page={$thisPage}&glm_action=events&option=tests&test=recurrence">Recurrence Times Generation Test</a></li>
+                </ul>
+            </td>
+        </tr>
+  {/if}
+    </table>
+        
+    <script type="text/javascript">
+        
+        jQuery(document).ready(function($) {
+            
+            /*
+             * Edit area tabs
+             */
+            $('.glm-settings-tab').click( function() {
+
+                // Clear tabl highlights and hide all tables
+                $('.glm-settings-tab').removeClass('nav-tab-active');
+                $('.glm-settings-table').addClass('glm-hidden');
+                
+                // Highlight selected tab
+                $(this).addClass('nav-tab-active');
+                
+                // Show selected table
+                var table = $(this).attr('data-show-table');
+                $('#' + table).removeClass('glm-hidden');
+                
+                if (table == 'glm-table-address') {
+                    initMap();
+                }
+                
+            });
+
+            // Flash certain elements for a short time after display      
+            $(".glm-flash-updated").fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500);
+                    
+        });
+    </script>