First deployment of GLM Members Contacts
authorChuck Scott <cscott@gaslightmedia.com>
Mon, 30 Nov 2015 21:23:24 +0000 (16:23 -0500)
committerChuck Scott <cscott@gaslightmedia.com>
Mon, 30 Nov 2015 21:23:24 +0000 (16:23 -0500)
23 files changed:
activate.php
classes/data/dataContacts.php
config.php [deleted file]
config/plugin.ini
controllers/admin.php [deleted file]
controllers/front.php [deleted file]
defines.php
glm-member-db-contacts.php
models/admin/member/contacts.php [new file with mode: 0644]
models/admin/members/contacts.php [new file with mode: 0644]
models/admin/profile/index.php [new file with mode: 0644]
models/admin/sample/index.php [new file with mode: 0644]
setup/adminMenus.php [new file with mode: 0644]
setup/adminTabs.php [new file with mode: 0644]
setup/permissions.php [new file with mode: 0644]
setup/rolesAndCapabilities.php [new file with mode: 0644]
setup/validActions.php [new file with mode: 0644]
uninstall.php
views/admin/member/contacts.html [new file with mode: 0644]
views/admin/members/contacts.html [new file with mode: 0644]
views/admin/profile/index.html [new file with mode: 0644]
views/admin/sample/header.html [new file with mode: 0644]
views/admin/sample/index.html [new file with mode: 0644]

index 5b702a9..c60ae1b 100644 (file)
@@ -70,72 +70,12 @@ class glmMembersContactsPluginActivate
         // Set current plugin version
         update_option('glmMembersDatabaseContactsPluginVersion', GLM_MEMBERS_CONTACTS_PLUGIN_VERSION);
 
-        /*
-         * Add contacts roles
-         *
-         * Note that the members_manager capability is created by the main Member DB plugin
-         */
-
-        // Members Manager - Full control of all members and their data
-        add_role(
-            'glm_members_manager',
-            'GLM Members Manager',
-            array(
-                'read' => true,
-                'glm_members_management' => true
-            )
-        );
-
-        // Own Member Manager - Full control of own member, location, facility (based on with which the contact is assocated)
-        add_role(
-            'glm_own_member_manager',
-            'GLM Own Member Manager',
-            array(
-                'read' => true,
-                'glm_members_management' => true    // but only allowed to manage their entity type (member, location, facility, ...)
-            )
-        );
-
-        // Member Contact - Standard contact for own member, location, facility, ... - no edit of member data
-        add_role(
-            'glm_member_contact',
-            'GLM Member Contact',
-            array(
-                'read' => true
-            )
-        );
-
-        // Restricted Member Contact - No login capability
-        add_role(
-            'glm_member_restricted_contact',
-            'GLM Member Restricted Contact',
-            array(
-                'read' => true
-            )
-        );
-
-        /*
-         * Add contacts capabilities
-         *
-         * Note that the glm_members_management capability is created by the main Member DB plugin
-         */
-
-        // May log in through members only area
-        $this->addRoleCapability(
-            'glm_members_login',
-            array(
-                'administrator' => true,
-                'glm_members_manager' => true,
-                'glm_own_member_manager' => true,
-                'glm_member_contact' => true,
-                'glm_member_restricted_contact' => false
-            )
-        );
-
+        // Set Roles and Capabilities for this plugin
+        require_once(GLM_MEMBERS_CONTACTS_PLUGIN_SETUP_PATH.'/rolesAndCapabilities.php');
     }
 
     /*
-     * Add a role capability to all current roles
+     * Add a capability to all current roles
      *
      * @param string $capability Name of capability to add
      * @param array $default Whether capability should be on by default
@@ -149,7 +89,7 @@ class glmMembersContactsPluginActivate
      * @return void
      * @access private
      */
-    private function addRoleCapability ($capability, $default)
+    private function addRoleCapability($capability, $default)
     {
         // Get list of role objects
         $roleObjects = $GLOBALS['wp_roles']->role_objects;
@@ -160,13 +100,6 @@ class glmMembersContactsPluginActivate
         // For each role object
         foreach ($roleObjects as $key => $role) {
 
-            // Uncomment to reset capabilities
-            /*
-            if ( isset($role->capabilities[$capability])) {
-                $role->remove_cap($capability);
-            }
-            */
-
             // Check if the role exists in list of editable roles and
             // the capability does not exist
             if (isset($roles[$key]) && ! isset($role->capabilities[$capability])) {
@@ -187,26 +120,36 @@ class glmMembersContactsPluginActivate
         }
     }
 
-}
 
+    /*
+     * Delete a capability from all current roles
+     *
+     * @param string $capability Name of capability to add
+     *
+     * @return void
+     * @access private
+     */
+    private function deleteRoleCapability($capability)
+    {
+        // Get list of role objects
+        $roleObjects = $GLOBALS['wp_roles']->role_objects;
+
+        // Get list of roles we can edit
+        $roles = get_editable_roles();
+
+        // For each role object
+        foreach ($roleObjects as $key => $role) {
+
+            if ( isset($role->capabilities[$capability])) {
+                $role->remove_cap($capability);
+            }
 
-/*
-// May be used to delete a capability from all roles
-add_action( 'admin_init', 'glmMembersDeleteCapabilities' );
-function glmMembersDeleteCapabilities(){
-
-    // Put capabilities to delete here
-    $delete_caps = array(
-            'glm_members_contact_manage_members'
-    );
-
-    global $wp_roles;
-    foreach ($delete_caps as $cap) {
-        foreach (array_keys($wp_roles->roles) as $role) {
-            $wp_roles->remove_cap($role, $cap);
         }
+
     }
+
+
+
 }
-*/
 
 ?>
index 2f5a462..72849a1 100644 (file)
@@ -24,7 +24,8 @@
  *          @release SVN: $Id: dataMembers.php,v 1.0 2011/01/25 19:31:47 cscott
  *          Exp $
  */
-class GlmDataContacts extends GlmDataAbstract {
+class GlmDataContacts extends GlmDataAbstract
+{
 
     /**
      * WordPress Database Object
@@ -41,151 +42,505 @@ class GlmDataContacts extends GlmDataAbstract {
      */
     public $config;
     /**
-        * Field definitions
-        *
-        * @var $ini
-        * @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;
-
-       /**
-        * Constructor
-        *
-        * @param object $d
-        *              database connection
-        *
-        * @return void
-        * @access public
-        */
-       function __construct($wpdb, $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;
+
+    /**
+     * 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_CONTACTS_PLUGIN_DB_PREFIX . 'contacts';
-
-               /*
-                * Table Data Fields
-                */
-
-/************* NOT UPDATED YET ******************/
-               $this->fields = array (
-
-                               'id' => array (
-                                               'field' => 'id',
-                                               'type' => 'integer',
-                                               'view_only' => true,
-                                               'use' => 'a'
-                               ),
-
-                               // Status
-                               'access' => array (
-                                               'field' => 'access',
-                                       'type' => 'list',
-                                       'list' => $this->config['memb_access'],
-                                           'l_blank' => true,
-                                       'required' => true,
-                                       'default' => 30,
-                                       'force_list' => true,
-                                       'use' => 'a'
-                               ),
-
-                               // Member Type
-                               'member_type' => array (
-                                               'field' => 'member_type',
-                                               'type' => 'pointer',
-                                           'p_table' => GLM_MEMBERS_PLUGIN_DB_PREFIX . 'member_type',
-                                           'p_field' => 'name',
-                                           'p_orderby' => 'name',
-                                           'p_blank' => true,
-                                               'required' => true,
-                                       'force_list' => true,
-                                               'use' => 'a'
-                               ),
-
-                       // Member Name
-                               'name' => array (
-                                               'field' => 'name',
-                                               'type' => 'text',
-                                               'required' => true,
-                                       'unique' => true,
-                                               'use' => 'a'
-                               ),
-
-                       // Member Name (stored by member updates) for sorting
-                       'member_slug' => array(
-                               'field' => 'member_slug',
-                               'type' => 'text',
-                               'required' => true,
-                               'use' => 'a'
-                       ),
-
-                       // Date created
-                       'created' => array (
-                               'field' => 'created',
-                               'type' => 'date',
-                               'required' => true,
-                               'use' => 'a'
-                       ),
-
-                       // Active Version
-                       'active_id' => array (
-                               'field' => 'id',
-                        'as' => 'active_id',
-                               'type' => 'pointer',
-                                 'p_table' => GLM_MEMBERS_PLUGIN_DB_PREFIX . 'member_info',
-                                 'p_field' => 'id',
-                                 'p_id' => 'member',
-                                 'p_where' => 'status = '.$this->config['status_numb']['Active'],
-                               'p_static' => true,
-                               'use' => 'gl'
-                       )
-
-               );
-
-/* - not updated for add-on yet
-               if (is_admin() && GLM_MEMBERS_PLUGIN_ADMIN_DEBUG_VERBOSE) {
-                   glmMembersAdmin::addNotice($this->fields, 'DataBlock', 'Table Fields: '.$this->table);
-               }
+        if (!$this->wpdb) {
+
+            // Save WordPress Database object
+            $this->wpdb = $wpdb;
+
+            // Save plugin configuration object
+            $this->config = $config;
+
+        }
+
+        /*
+         * Table Name
+         */
+        $this->table = GLM_MEMBERS_CONTACTS_PLUGIN_DB_PREFIX . 'contacts';
+
+        /*
+         * Table Data Fields
+         */
+
+        $this->fields = array (
+
+            'id' => array (
+                'field' => 'id',
+                'type' => 'integer',
+                'view_only' => true,
+                'use' => 'a'
+            ),
+
+            // Active flag
+            'active' => array (
+                'field' => 'active',
+                'type' => 'checkbox',
+                'default' => true,
+                'view_only' => $limitedEdit,
+                'use' => 'a'
+            ),
+
+            // Status
+            'access' => array (
+                'field' => 'access',
+                'type' => 'list',
+                'list' => $this->config['access'],
+                    'l_blank' => true,
+                'required' => true,
+                'default' => 30,
+                'force_list' => true,
+                'view_only' => $limitedEdit,
+                'use' => 'a'
+            ),
+
+            // First Name
+            'fname' => array (
+                'field' => 'fname',
+                'type' => 'text',
+                'required' => true,
+                'use' => 'a'
+            ),
+
+            // Last Name
+            'lname' => array (
+                'field' => 'lname',
+                'type' => 'text',
+                'required' => true,
+                'use' => 'a'
+            ),
+
+            // Type (Individual, role, ...)
+            'contact_type' => array (
+                'field' => 'contact_type',
+                'type' => 'list',
+                'list' => $this->config['contact_type'],
+                'required' => true,
+                'default' => $this->config['contact_type_numb']['Personal'],
+                'force_list' => true,
+                'view_only' => $limitedEdit,
+                'use' => 'a'
+            ),
+
+            // Contact WordPress Login Role
+            'contact_role' => array (
+                'field' => 'contact_role',
+                'type' => 'list',
+                'list' => $this->config['contact_role'],
+                'required' => true,
+                'default' => $this->config['contact_role_numb']['RestrictedContact'],
+                'force_list' => true,
+                'view_only' => $limitedEdit,
+                'use' => 'a'
+            ),
+
+            // Contact WordPress Login Role Short for display only
+            'contact_role_short' => array (
+                'field' => 'contact_role',
+                'as' => 'contact_role_short',
+                'type' => 'list',
+                'list' => $this->config['contact_role_short'],
+                'use' => 'lged'
+            ),
+
+            // Organization name
+            'org' => array (
+                    'field' => 'org',
+                    'type' => 'text',
+                    'use' => 'a'
+            ),
+
+            // Title/Position
+            'title' => array (
+                    'field' => 'title',
+                    'type' => 'text',
+                    'use' => 'a'
+            ),
+
+            // Description - Displayed -
+            'descr' => array (
+                    'field' => 'descr',
+                    'type' => 'text',
+                    'use' => 'a'
+            ),
+
+            // Image
+            'image' => array(
+                    'field'    => 'image',
+                    'type'     => 'image',
+                    'use'      => 'a'
+            ),
+
+            // Address line 1
+            'addr1' => array (
+                'field' => 'addr1',
+                'type' => 'text',
+                'use' => 'a'
+            ),
+
+            // Address line 2
+            'addr2' => array (
+                'field' => 'addr2',
+                'type' => 'text',
+                'use' => 'a'
+            ),
+
+            // City
+            'city' => array (
+                'field' => 'city',
+                'type' => 'pointer',
+                    'p_table' => GLM_MEMBERS_PLUGIN_DB_PREFIX . 'cities',
+                    'p_field' => 'name',
+                    'p_orderby' => 'name',
+                    'p_blank' => true,
+                'force_list' => true,
+                'use' => 'a'
+            ),
+
+            // State
+            'state' => array (
+                'field' => 'state',
+                'type' => 'list',
+                'list' => $this->config['states'],
+                'default' => 'MI',
+                'force_list' => true,
+                'use' => 'a'
+            ),
+
+            // ZIP / Postal Code
+            'zip' => array (
+                'field' => 'zip',
+                'type' => 'text',
+                'use' => 'a'
+            ),
+
+            // Country
+            'country' => array (
+                'field' => 'country',
+                'type' => 'list',
+                'list' => $this->config['countries'],
+                'default' => 'US',
+                'force_list' => true,
+                'use' => 'a'
+            ),
+
+/* Not using now
+            // Latitude
+            'lat' => array(
+                'field'    => 'lat',
+                'type'     => 'float',
+                'default'  => $this->config['settings']['maps_default_lat'],
+                'use'      => 'a'
+            ),
+
+            // Longitude
+            'lon' => array(
+                'field'    => 'lon',
+                'type'     => 'float',
+                'default'  => $this->config['settings']['maps_default_lon'],
+                'use'      => 'a'
+            ),
 */
 
-       }
+            // URL
+            'url' => array (
+                'field' => 'url',
+                'type' => 'text',
+                'use' => 'a'
+            ),
+
+            // Office Phone
+            'office_phone' => array(
+                'field'    => 'office_phone',
+                'type'     => 'phone',
+                'use'      => 'a'
+            ),
+
+            // Office Phone
+            'home_phone' => array(
+                'field'    => 'home_phone',
+                'type'     => 'phone',
+                'use'      => 'a'
+            ),
+
+            // Mobile Phone
+            'mobile_phone' => array(
+                'field'    => 'mobile_phone',
+                'type'     => 'phone',
+                'use'      => 'a'
+            ),
+
+            // Alternate Phone
+            'alt_phone' => array(
+                'field'    => 'alt_phone',
+                'type'     => 'phone',
+                'use'      => 'a'
+            ),
+
+            // FAX Number
+            'fax' => array(
+                    'field'    => 'fax',
+                    'type'     => 'phone',
+                    'use'      => 'a'
+            ),
+
+            // E-Mail Address
+            'email' => array(
+                'field'    => 'email',
+                'type'     => 'email',
+                'view_only' => $limitedEdit,
+                'use'      => 'nigedl'
+            ),
+
+            // Altername E-Mail Address
+            'alt_email' => array(
+                    'field'    => 'alt_email',
+                    'type'     => 'email',
+                    'use'      => 'a'
+            ),
+
+            // User Name - new/insert
+            'username' => array(
+                'field'    => 'username',
+                'type'     => 'text',
+                'required' => 'text',
+                'use'      => 'ni'
+            ),
+
+            // User Name - display only
+            'username_display' => array(
+                'field'    => 'username',
+                'type'     => 'text',
+                'use'      => 'lged'
+            ),
+
+            // Password
+            'password' => array(
+                'field'    => 'password',
+                'type'     => 'password',
+                    'pw_type' => 'strong',
+                'minLength' => 8,
+                'use'      => 'a'
+            ),
+
+            // Notes - not displayed
+            'notes' => array(
+                'field'    => 'notes',
+                'type'     => 'text',
+                'view_only' => $limitedEdit,
+                'use'      => 'a'
+            ),
+
+            // Create Time
+            'create_time' => array (
+                'field' => 'create_time',
+                'type' => 'datetime',
+                'use' => 'i'
+            ),
+
+            // Create Time
+            'create_time_update' => array (
+                'field' => 'create_time',
+                'type' => 'datetime',
+                'view_only' => true,
+                'use' => 'lgeu'
+            ),
+
+            // Last Modify Time
+            'modify_time' => array (
+                'field' => 'modify_time',
+                'type' => 'datetime',
+                'use' => 'lgeu'
+            ),
+
+            // Reference Type - Insert new record
+            'ref_type_insert' => array (
+                'field' => 'ref_type',
+                'type' => 'integer',
+                'required' => true,
+                'use' => 'i'
+            ),
+
+            // Reference Type - Output only
+            'ref_type' => array (
+                'field' => 'ref_type',
+                'type' => 'list',
+                    'list' => $this->config['ref_type'],
+                'required' => true,
+                'use' => 'lged'
+            ),
+
+            // Reference Target - Insert new record and for recall
+            'ref_dest' => array (
+                'field' => 'ref_dest',
+                'type' => 'integer',
+                'required' => true,
+                'use' => 'ilged'
+            ),
+
+            // Reference Destination Name
+            'ref_dest_name' => array (
+                'field' => 'ref_dest',
+                'as' => 'ref_dest_name',
+                'type' => 'pointer',
+                    'p_table' => GLM_MEMBERS_PLUGIN_DB_PREFIX . 'members',
+                    'p_field' => 'name',
+                    'p_orderby' => 'name',
+                    'p_blank' => true,
+                'required' => true,
+                'use' => 'lged'
+            )
+
+        );
+
+    }
+
+    public function entryPostProcessing($r, $a)
+    {
+
+        // Only run these tests for list, get, edit, and delete
+        if (in_array($a, array('l', 'g', 'e', 'd', 'u'))) {
+
+            // Select proper table
+            $table = GLM_MEMBERS_PLUGIN_DB_PREFIX.$this->config['ref_type_table'][$r['ref_type']['value']];
+
+            $dest = $this->wpdb->get_row("SELECT name FROM $table WHERE id = ".$r['ref_dest'].";");
+            $r['ref_dest_name'] = $dest->name;
+
+        }
+
+        return $r;
+    }
+
+    /*
+     * Get the contact's "Permissions" (contact_role)
+     *
+     * This value maps to the contact_role arrays in plugin.ini.
+     *
+     * @param integer $id ID of the contact record.
+     *
+     * @return array
+     *
+     *      array(
+     *          'contactRole'   Integer  Contact role value for use with "contact_role" arrays in plugin.ini
+     *          'wpRole'        String   Wordpress role slug
+     *      )
+     *
+     */
+    public function getWpRole($id) {
+
+        // Get the user's current "Permissions" (contact_role) and wordpress user data
+        $contactRole = $this->wpdb->get_var("SELECT contact_role FROM ".$this->table." WHERE id = $id;");
+
+        $r = array(
+            'contactRole' => $contactRole,
+            'wpRole' => $this->config['contact_role_wordpress'][$contactRole]
+        );
+
+        return $r;
+    }
+
+    /*
+     * Determine if Wordpress user exists by E-Mail address and/or by username
+     *
+     * @param string $email E-mail address to check
+     * @param string $username Username to check (optional)
+     *
+     * @return array
+     *
+     *      array(
+     *          'worpress'   Boolean if exists in Wordpress
+     *          'wpUser'     If user exists in Wordpress, this is the Wordpress user data
+     *          'contacts'   Boolean if user exists in contacts
+     *      )
+     *
+     */
+    public function checkContact($email, $username = false)
+    {
+
+        $r = array(
+            'wpUserEmail' => false,
+            'wordpressEmail' => false,
+            'wpUserLogin' => false,
+            'wordpressLogin' => false,
+            'wpUser' => false,
+            'contactsEmail' => false,
+            'contactsUsername' => false
+        );
+
+        // If E-mail address is not supplied
+        if (trim($email) == '') {
+            return false;
+        }
+
+        // Check Wordpress
+        $r['wpUserEmail'] = get_user_by( 'email', $email );
+        If ($r['wpUserEmail']) {
+            $r['wordpressEmail'] = true;
+        }
+        $r['wpUserLogin'] = get_user_by( 'login', $username );
+        If ($r['wpUserLogin']) {
+            $r['wordpressLogin'] = true;
+        }
+
+        // Check Contacts
+        $contact = $this->wpdb->get_row("SELECT * FROM ".GLM_MEMBERS_PLUGIN_DB_PREFIX . "contacts WHERE email = '$email';", ARRAY_A);
+        if ($contact !== null) {
+            $r['contactsEmail'] = true;
+        }
+        $contact = $this->wpdb->get_row("SELECT * FROM ".GLM_MEMBERS_PLUGIN_DB_PREFIX . "contacts WHERE username = '$username';", ARRAY_A);
+        if ($contact !== null) {
+            $r['contactsUsername'] = true;
+        }
+
+        return $r;
+
+    }
+
+
 
 }
 
diff --git a/config.php b/config.php
deleted file mode 100644 (file)
index 27d17c8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-/**
- * Gaslight Media Members Database Contacts Child Plugin
- *
- * Get plugin configuration
- *
- * Note that most of the configuration data comes from the main GLM Member DB plugin
- * and will be passed back when registering this add-on.
- */
-
-// Get plugin configuration
-$configData = parse_ini_file(GLM_MEMBERS_CONTACTS_PLUGIN_PATH.'/config/plugin.ini', true);
-$config = $configData['common'];
-
-// Check for config value replacements in the current theme
-$currentThemeDirectory = get_template_directory();
-if (file_exists($currentThemeDirectory.'/glm-member-db-contacts/plugin.ini')) {
-
-    // Read in the ini file from the theme
-    $themeIni = parse_ini_file($currentThemeDirectory.'/glm-member-db-contacts/plugin.ini');
-
-    // Replace parameters that are in the theme ini file
-    $config = array_replace($config, $themeIni);
-
-}
-
-?>
index a2a5cb2..d1481bc 100644 (file)
@@ -4,3 +4,36 @@
 ;
 
 [common]
+;
+; Contact Type
+;
+contact_type[0] = 'None'
+contact_type[10] = 'Personal'
+contact_type[20] = 'Role'
+
+contact_type_numb['None'] = 0
+contact_type_numb['Personal'] = 10
+contact_type_numb['Role'] = 20
+
+;
+; Contact Roles
+;
+contact_role[10] = "All Members Manager - Full rights to modifiy any member's information"
+contact_role[20] = "Entity Manager - Rights to modify all information associated with contact's entity (member, location, facility, ...)"
+contact_role[30] = 'Log-in Contact - Contact may log-in, but not modify associated information'
+contact_role[40] = 'Restricted Contact - No login privileges, used only for information and display'
+
+contact_role_short[10] = "All Manager";
+contact_role_short[20] = 'Entity Manager';
+contact_role_short[30] = 'Login Only';
+contact_role_short[40] = 'Restricted';
+
+contact_role_numb['MembersManager'] = 10
+contact_role_numb['EntityManager'] = 20
+contact_role_numb['LogInContact'] = 30 
+contact_role_numb['RestrictedContact'] = 40
+
+contact_role_wordpress[10] = 'glm_members_manager'
+contact_role_wordpress[20] = 'glm_members_own_entity_manager'
+contact_role_wordpress[30] = 'glm_members_member_contact'
+contact_role_wordpress[40] = 'glm_members_restricted_contact'
\ No newline at end of file
diff --git a/controllers/admin.php b/controllers/admin.php
deleted file mode 100644 (file)
index 4a095d9..0000000
+++ /dev/null
@@ -1,606 +0,0 @@
-<?php
-/**
- * Gaslight Media Members Database
- * Contacts Add-On Admin Controller
- *
- * PHP version 5.5
- *
- * @category glmWordPressPlugin
- * @package  glmMembersDatabase
- * @author   Chuck Scott <cscott@gaslightmedia.com>
- * @license  http://www.gaslightmedia.com Gaslightmedia
- * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
- * @link     http://dev.gaslightmedia.com/
- */
-
-/**
- * Array of valid menu items and actions.
- *
- * These are the valid menu items and actions that are passed to the main
- * GLM Members DB plugin, along with other information about this add-on,
- * using the glm-member-db-register-addon hook.
- */
-$glmMembersContactsValidActions = array(
-    'admin' => array(
-        'member' => array (
-            'contacts'
-        )
-    ),
-    'front' => array(
-    )
-);
-
-// Load glmPluginSupport class from main GLM Member DB plugin
-require_once (GLM_MEMBERS_CONTACTS_MAIN_PLUGIN_PATH . '/classes/glmPluginSupport.php');
-
-// Load Smarty Template Support from main GLM Member DB plugin
-require_once (GLM_MEMBERS_CONTACTS_MAIN_PLUGIN_PATH . '/lib/smartyTemplateSupport.php');
-
-/**
- * Admin Controller Class
- *
- * This is one of perhaps multiple controller classes that provide
- * controller services for a major portion of this plugin. Typically
- * there are such classes for Admin and Front-End functionality, but
- * there could be others.
- *
- * This controller class performs all admin related operations for
- * this plugin by calling the appropriate model and merging the resulting
- * data with the appropriate view to produce any output.
- *
- * All requests for this controller class come through WordPress admin
- * menus via hooks that "call back" methods in this class for each admin
- * menu item in this plugin. Form submissions from an admin page selected
- * by a particular menu item are directed to WordPress using the page
- * reference of that menu item. Because of this, the callback for a form
- * submission is also handled by the callback target method used by that
- * menu item.
- *
- * Admin form submissions must use the URI for one of this plugin's
- * menu items. The form post parameters may also provide an "action" name
- * in the case where the default menu item behavior is not desired. A
- * pathname for the model to execute is then complied using the menu
- * item name as the name of a directory under models/admin and the
- * requested action as the file name of the model to execute. The name
- * "index" would be the default menu item action model. In essence the
- * controller locates the model by menu item name and action name. for
- * example...
- *
- * models/admin/members/index.php
- * models/admin/members/display.php
- *
- * Similarly, the view associated with the action would be in a directory
- * named the same as the model, and the view file would be named "index"
- * or the name of the action.
- *
- * These hooks are established using the WordPress add_action()
- * function and the configureMenus() method below. Other methods in this
- * class then recieve any request from a menu item selection or form
- *
- * submission associated with a menu item by WordPress calling one of the
- * "callback" methods below.
- *
- * The callback methods do nothing other than to call the controller()
- * method and passing it the name of the menu item assocaiated with the
- * callback.
- *
- * The controller() method determines which model to execute, executes
- * that model, determines which view to merge with the data returned by
- * the model, creates output from the result of that merge, and sends
- * that output to the user.
- *
- * In situations where it may be desired to output directly to the browser
- * without being contained in the admin Dashboard, the contructor can be
- * directed
- * to bypass setting up the admin hooks and execute the controller() method
- * directly then exit. This results in output from the model/view withing being
- * contained in the normal WordPress dashboard context. To trigger this use the
- * following two form fields.
- *
- * glm_display_direct = 'true'
- * glm_menu_item = (menu item name associated with the desired model)
- *
- * (no prameters)
- *
- * @return void
- * @access public
- */
-class glmMembersContactsAdmin extends GlmPluginSupport
-{
-
-    /**
-     * WordPress Database Object
-     *
-     * @var $wpdb
-     * @access public
-     */
-    public $wpdb;
-    /**
-     * Plugin Configuration Data
-     *
-     * @var $config
-     * @access public
-     */
-    public $config;
-
-    /**
-     * Admin Controller Constructor
-     *
-     * This contructor is executed by the main plugin index file when the site
-     * Dashboard is displayed. It's responsible for setting up any needed hooks
-     * into WordPress and setting up any support classes required to do admin
-     * work.
-     *
-     * (no prameters)
-     *
-     * @return void
-     * @access public
-     */
-    public function __construct ($wpdb, $config)
-    {
-
-        // Save WordPress Database object
-        $this->wpdb = $wpdb;
-
-        // Save plugin configuration object
-        $this->config = $config;
-
-        // Hook into menu created by main GLM Member DB plugin
-        // If we don't do it this way, the member db menus may not be setup
-        add_action('glm-member-db-add-menu', array($this, 'glmMembersAddMenusContacts'));
-
-        add_filter('glm-member-db-add-tab-for-members', array($this, 'glmMembersAddTabForMembers'));
-
-    }
-
-    public function glmMembersAddTabForMembers($addOnTabs)
-    {
-
-        $newTabs = array(
-            array(
-                'text' => 'New Tab',
-                'action' => 'list'
-            ),
-            array(
-                'text' => 'Another Tab',
-                'action' => 'anotherAction'
-            )
-        );
-        $addOnTabs = array_merge($addOnTabs, $newTabs);
-
-        return $addOnTabs;
-
-    }
-
-
-    /**
-     * Called by glm-member-db-add-menu hook from main GLM Member DB plugin
-     *
-     * This adds an admin_menu action that calls the configureMenus() method to
-     * actually do the work of adding the menus.
-     *
-     * Since there needs to be an add_action() call with 'admin_menu" and have that
-     * then link in an action that can be called to do the menu pages, we need this
-     * intermediate method.
-     *
-     * @return void
-     * @access public
-     */
-    public function glmMembersAddMenusContacts()
-    {
-
-        // Add hooks to WordPress
-        add_action('admin_menu', array($this, 'configureMenus'));
-
-    }
-
-    /**
-     * Configure WordPress Menus for this Plugin
-     *
-     * This method is called by an add_action() hook setup in the contructor. We
-     * do it
-     * this way so that the menu related functions of WordPress are in scope
-     * when creating
-     * the additional menu items. WordPress will execute this call-back method
-     * when building
-     * its Dashboard menus.
-     *
-     * add menu function reference
-     *      add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position)
-     *      add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function)
-     *
-     * (no prameters)
-     *
-     * @return void
-     * @access public
-     */
-    public function configureMenus ()
-    {
-
-        // A main Menu Test
-        add_menu_page(
-            'Test Page 1',                                      // Page title
-            'Test 1',                                           // Menu title
-            'glm_members_edit',                                 // Capability
-            'glm-members-admin-menu-test-1',                    // Menu slug
-            array($this, 'glmMembersAdminMenuTest'),            // Function to execute page
-            false,                                              // Icon URL
-            '91.124'                                            // Menu position
-        );
-
-        // A Test Sub-Menu
-        add_submenu_page(
-            'glm-members-admin-menu-members',                   // Parent slug
-            'Contacts',                                         // Page title
-            'Contacts',                                         // Menu Title
-            'glm_members_edit',                                 // Capability required
-            'glm-members-admin-menu-contacts',                  // Menu slug
-            array($this, 'glmMembersAdminMenuTest')             // Function to execute page
-        );
-
-        // A Test Sub-Menu
-        add_submenu_page(
-            'glm-members-admin-menu-test-1',                    // Parent slug
-            'Sub-Test',                                         // Page title
-            '&nbsp;&nbsp;Sub-Test',                                         // Menu Title
-            'glm_members_edit',                                 // Capability required
-            'glm-members-admin-menu-sub-test-1',                  // Menu slug
-            array($this, 'glmMembersAdminMenuTest')             // Function to execute page
-        );
-
-    }
-
-    /*
-     * Menu item specific "Callback" methods
-     *
-     * These methods are called by WordPress when specific menu items are
-     * selected by the
-     * user or a form action is submitted associated with the menu item.
-     *
-     * These methods call the controller and pass it the menu item that was
-     * called
-     * but perform no other work.
-     *
-     */
-
-    // A test menu
-    function glmMembersAdminMenuTest() {
-//      $this->controller('contacts');
-        echo "TEST";
-    }
-
-
-    /**
-     * Contacts Admin controller
-     *
-     * This method is called by a plugin menu method. It is responsible for
-     * executing the approriate model, combining model data with a view, and
-     * outputing the result. It is therefore the core of the controller.
-     *
-     * This controller is supplied a menu item name and then determines if
-     * there is an additional action related to that menu item that needs to be
-     * executed rather than the default menu action.
-     *
-     * All models should return an array containing the following.
-     *
-     * 'status'
-     *
-     * True if successfull and false if there was a fatal failure.
-     *
-     * 'menuItemRedirect'
-     *
-     * If not false, provides a menu item the controller should
-     * execute after this one. Normally if this is used, there would also be a
-     * modelRedirect value supplied as well.
-     *
-     * 'modelRedirect'
-     *
-     * If not false, provides an action the controller should execute after
-     * this one.
-     *
-     * '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.
-     *
-     * For a better explanation of how this all works, see the description for
-     * this class.
-     *
-     * Controller parameters
-     *
-     * @param string $menuItem
-     *            Name of the menu item that is being processed
-     *
-     * @return void
-     * @access public
-     */
-    public function controller ($menuItem, $action = false)
-    {
-        $errorMsg = '';
-
-        /*
-         * Because WordPress insists on forcing the timezone to UTC
-         * we need to save the current timezone setting, set the one
-         * we want to use, and then restore it after we're all done
-         * (see bottom of this script).
-         */
-        $defaultTimeZone = date_default_timezone_get();
-        date_default_timezone_set($this->config['settings']['time_zone']);
-
-        if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG) {
-
-            // Also turn on SQL error messages
-            $this->wpdb->show_errors();
-
-            // If debug is VERBOSE
-            $consts = get_defined_constants(true);
-            if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG_VERBOSE) {
-                $this->addNotice("<pre>".print_r($_SERVER,1).'</pre>', 'DataBlock', 'Server Defines');
-                $this->addNotice('<pre>'.print_r($consts,1).'</pre>', 'DataBlock', 'Defined Parameters');
-            // Not verbose
-            } else {
-                $ourConsts  = array();
-                foreach ($consts['user'] as $k => $v) {
-                    if (strncmp($k, 'GLM_MEMBERS_PLUGIN', 18) == 0) {
-                        $ourConsts[$k] = $v;
-                    }
-                }
-                $this->addNotice('<pre>'.print_r($ourConsts,1).'</pre>', 'DataBlock', 'Defined Parameters');
-            }
-
-            $this->addNotice('<pre>'.print_r($this->config,1).'</pre>', 'DataBlock', 'Configuration Settings');
-            $this->addNotice("<pre>".print_r($_REQUEST,1)."</pre>", 'DataBlock', "Request Data");
-            if (isset($_FILES)) {
-                $this->addNotice("<pre>".print_r($_FILES,1)."</pre>", 'DataBlock', "Request Files Data");
-            }
-        } else {
-            $this->clearNotices();
-        }
-
-        /*
-         * Determine model to execute
-         */
-
-        // Default action is "index" if an action wasn't specified in the controller call
-        if (!$action) {
-            $action = 'index';
-        }
-
-        // Get any requested "action" from a form submission and modify path/name
-        // accordingly. This modifies the previously set $action.
-        if (isset($_REQUEST['glm_action']) && $_REQUEST['glm_action'] != '') {
-            $a = sanitize_text_field($_REQUEST['glm_action']);
-            if ($a != '') {
-                $action = $a;
-            }
-        }
-
-        // Loop till we have a final action
-        $loopCheck = 0;
-        $actionData = false;
-        do {
-
-            if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG) {
-                $this->addNotice("<b>Requested Action:</b> Menu item = $menuItem, Action = $action", 'Process');
-            }
-
-            $modelRedirect = false;
-
-            // Verify that we have the requested menu item in the valid actions
-            if (!isset($GLOBALS['glmMembersAdminValidActions'][$menuItem])) {
-
-                if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG) {
-                    $this->addNotice('<b>Error in Admin Controller:</b> Menu Item not specified!', 'Alert');
-                }
-
-                $modelRedirect = true;
-                $menuItem = 'error';
-                $action = 'index';
-                $errorMsg .= "<b>Model doesn't exist:</b> ".$modelName;
-
-            }
-
-            // Verify Menu item and action using array at top of this file
-            if (! isset($GLOBALS['glmMembersAdminValidActions'][$menuItem]) ||
-                     ! in_array($action, $GLOBALS['glmMembersAdminValidActions'][$menuItem])) {
-
-                if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG) {
-                    $this->addNotice('<b>Error in Admin Controller:</b> Requested Menu Item is invalid! - '.$menuItem, 'Alert');
-                }
-
-                $menuItem = 'error';
-                $action = 'badAction';
-            }
-
-            /*
-             * Execute the selected model
-             */
-
-            // Build model and path and class names
-            $modelName = GLM_MEMBERS_PLUGIN_PATH . '/models/admin/' . $menuItem .
-                     '/' . $action . '.php';
-            $className = 'GlmMembersAdmin_' . $menuItem . '_' . $action;
-
-            // If model file doesn't exist - we have an error
-            if (!file_exists($modelName)) {
-
-                if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG) {
-                    $this->addNotice("<b>Error in Admin Controller:</b> Model file doesn't exist - ".$modelName, 'Alert');
-                }
-
-                $modelRedirect = true;
-                $menuItem = 'error';
-                $action = 'index';
-                $errorMsg .= "<b>Model doesn't exist:</b> ".$modelName;
-
-            // Otherwise, load and run the model
-            } else {
-
-                // Load the model file
-                 require_once ($modelName);
-
-                // check for an invalid model class name
-                if (!class_exists($className)) {
-
-                    if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG) {
-                        $this->addNotice("<b>Error in Admin Controller:</b> Invalid Model Class Name - ".$className, 'Alert');
-                    }
-
-                    $modelRedirect = true;
-                    $menuItem = 'error';
-                    $action = 'index';
-                    $errorMsg .= "<b>Model class doesn't exist:</b> ".$className;
-
-                } else {
-
-                    // Check if this is a re-direct with parameters
-                    $args = false;
-
-                    // Instantiate the model and ask it to perform the work
-                    $model = new $className($this->wpdb, $this->config);
-                    $results = $model->modelAction($actionData);
-
-                    // Check if there's been a model redirect request
-                    if ($results['modelRedirect']) {
-
-                        $this->addNotice('<pre>'.print_r($results,1).'</pre>', 'DataBlock', 'Model Redirect');
-
-                        // Set the new model action
-                        $action = $results['modelRedirect'];
-
-                        // Check if there's also a menu item change
-                        if ($results['menuItemRedirect']) {
-                            $menuItem = $results['menuItemRedirect'];
-                        }
-
-                        // Check if there's data to pass to the new model
-                        if (isset($results['data']) && count($results['data']) > 0) {
-                            $actionData = $results['data'];
-                        }
-
-                        $modelRedirect = true;
-                    }
-
-                    // Get the specified view file
-                    $view = false;
-                    if (isset($results['view'])) {
-                        $view = $results['view'];
-                    }
-
-                    // Check for invalid or missing view file
-                    if (!$view || !is_file(GLM_MEMBERS_PLUGIN_PATH . '/views/'.$view)) {
-
-                        if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG) {
-                            $this->addNotice("<b>Error in Admin Controller:</b> Requested View file doesn't exist - ".$view, 'Alert');
-                        }
-
-                        $modelRedirect = true;
-                        $menuItem = 'error';
-                        $action = 'index';
-                        $errorMsg .= "<b>Bad or missing view file:</b> ".$view;
-                    }
-
-                } // model class exists
-            }
-
-            // This is just a sanity check on this loop to keep it from getting out of control
-            if (++$loopCheck > 10) {
-                die('<h1>Serious failure looping on model load in "controllers/admin.php".</h1>');
-            }
-
-            if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG && $modelRedirect) {
-                $this->addNotice('<b>Redirecting...</b>', 'Process');
-            }
-
-            // Loop again if there's a model redirect
-
-        } while ($modelRedirect);
-
-        /*
-         * Check model results
-         */
-
-        // Get suggested view
-        $view = $results['view'];
-
-        // If there's a general model failure use the error view
-        if (! $results['status']) {
-            $view = 'admin/error/index.html';
-        }
-
-        // Check for modified settings to save in conf
-        if (isset($results['settings'])) {
-            while (list($key, $val) = each($results['settings'])) {
-                $this->config['settings'][$key] = $val;
-            }
-        }
-
-        /*
-         * Merge data returned from the model with the selected view
-         */
-
-        // Load Smarty Template support
-        $smarty = new smartyTemplateSupport();
-
-        // Add standard template parameters
-        $smarty->templateAssign ( 'adminDebug', GLM_MEMBERS_PLUGIN_ADMIN_DEBUG);
-        $smarty->templateAssign ( 'adminURL', GLM_MEMBERS_PLUGIN_ADMIN_URL);
-        $smarty->templateAssign ( 'baseURL', GLM_MEMBERS_PLUGIN_BASE_URL);
-        $smarty->templateAssign ( 'thisURL', GLM_MEMBERS_PLUGIN_CURRENT_URL );
-        $smarty->templateAssign ( 'thisPage', (isset($_REQUEST['page']) ? $_REQUEST['page']: '') );
-        $smarty->templateAssign ( 'glmPluginName', GLM_MEMBERS_PLUGIN_NAME );
-        $smarty->templateAssign ( 'glmPluginMediaURL', GLM_MEMBERS_PLUGIN_MEDIA_URL );
-        $smarty->templateAssign ( 'thisYear', date ( 'Y' ) );
-        $smarty->templateAssign ( 'ref_type_numb', $this->config['ref_type_numb']);
-        $smarty->templateAssign ( 'settings', $this->config['settings']);
-        $smarty->templateAssign ( 'terms', $this->config['terms']);
-
-        // Add data from model to Smarty template
-        if (is_array($results['data']) && count($results['data']) > 0) {
-            foreach ($results['data'] as $k => $d) {
-                $smarty->templateAssign($k, $d);
-            }
-        }
-
-        $smarty->templateAssign ( 'thisAction', $action);
-
-
-        // If there's an error message, add that also
-        if ($errorMsg != '') {
-            $smarty->templateAssign('errorMsg', $errorMsg);
-        }
-
-        // If view debug has been requested
-        if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG) {
-
-            glmMembersAdmin::addNotice("<b>Template File:</b> $view", 'Process');
-
-            $x = $smarty->template->getTemplateVars();
-
-            if (GLM_MEMBERS_PLUGIN_ADMIN_DEBUG) {
-                glmMembersAdmin::addNotice($x, 'DataBlock', 'Template Parameters');
-            }
-
-            $templateVars = '<pre>' . print_r($x, 1) . '</pre>';
-            glmMembersAdmin::addNotice($templateVars, 'Template Parameters', 'Process');
-
-        }
-
-        // Generate output from model data and view
-
-        $smarty->template->display($view);
-
-        // Restore timezone that was set before our code was called
-        date_default_timezone_set($defaultTimeZone);
-
-    }
-
-}
-
-
diff --git a/controllers/front.php b/controllers/front.php
deleted file mode 100644 (file)
index 1d8daf9..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-<?php
-/**
- * Gaslight Media Members Database
- * Contacts Add-On Front-End Controller
- *
- * PHP version 5.5
- *
- * @category glmWordPressPlugin
- * @package  glmMembersDatabase
- * @author   Chuck Scott <cscott@gaslightmedia.com>
- * @license  http://www.gaslightmedia.com Gaslightmedia
- * @release  front.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
- * @link     http://dev.gaslightmedia.com/
- */
-
-/**
- * Array of valid menu items and actions.
- *
- *
- * The higher level elements are valid menu items. These correlate to
- * actual menu or sub menu items that are hooks back to this controller
- * class.
- *
- * The lower level items below each menu item are actions that may be specified
- * by a "glmMembersAction" form field.
- */
-$GLOBALS['glmMembersFrontValidActions'] = array(
-
-        'members' => array(
-                'list',
-                'detail'
-        ),
-        'error' => array(
-                'index',
-                'badAction'
-        )
-
-);
-
-// Load glmPluginSupport class
-require_once (GLM_MEMBERS_CONTACTS_MAIN_PLUGIN_PATH . '/classes/glmPluginSupport.php');
-
-/*
- * This class controls which models are use for front-end functionality
- * of this plugin.
- */
-class glmMembersCOntactsFront extends GlmPluginSupport
-{
-
-    /**
-     * WordPress Database Object
-     *
-     * @var $wpdb
-     * @access public
-     */
-    public $wpdb;
-
-    /**
-     * Plugin Configuration Data
-     *
-     * @var $config
-     * @access public
-     */
-    public $config;
-
-    public function __construct ($wpdb, $config)
-    {
-
-        // Save WordPress Database object
-        $this->wpdb = $wpdb;
-
-        // Save plugin configuration object
-        $this->config = $config;
-
-    }
-
-    /**
-     * Front-End controller
-     *
-     * This method is called by a plugin menu method. It is responsible for
-     * executing the approriate model, combining model data with a view, and
-     * outputing the result. It is therefore the core of the controller.
-     *
-     * This controller is supplied a menu item name and then determines if
-     * there is an additional action related to that menu item that needs to be
-     * executed rather than the default menu action.
-     *
-     * All models should return an array containing the following.
-     *
-     * 'status'
-     *
-     * True if successfull and false if there was a fatal failure.
-     *
-     * 'menuItemRedirect'
-     *
-     * If not false, provides a menu item the controller should
-     * execute after this one. Normally if this is used, there would also be a
-     * modelRedirect value supplied as well.
-     *
-     * 'modelRedirect'
-     *
-     * If not false, provides an action the controller should execute after
-     * this one.
-     *
-     * '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.
-     *
-     * For a better explanation of how this all works, see the description for
-     * this class.
-     *
-     * Controller parameters
-     *
-     * @param object $atts
-     *            Shortcode attributes
-     * @param string $content
-     *            Content included by an Enclosing format shortcode
-     *
-     * @return void
-     * @access public
-     */
-    public function controller ($atts, $content = null, $shortcode)
-    {
-
-        // Set shortcode attribute defaults
-/*
-        switch ($shortcode) {
-
-            case 'glm-members-list':
-                $action = 'list';
-                $request = shortcode_atts(
-                        array(
-                                'map' => true,
-                                'category' => false,
-                                'category-name' => false,
-                                'alpha' => false,
-                                'search' => false,
-                                'amenities' => false,
-                                'detail-page' => false,
-                                'show' => false
-                        ),
-                        $atts,
-                        'glm-members'
-                        );
-                break;
-
-            case 'glm-member-detail':
-                $action = 'detail';
-                $request = shortcode_atts(
-                        array(
-                                'map' => true,
-                                'id' => false,
-                                'show' => false
-                        ),
-                        $atts,
-                        'glm-members'
-                        );
-                break;
-
-        }
-*/
-        /*
-         * Because WordPress insists on forcing the timezone to UTC
-         * we need to save the current timezone setting, set the one
-         * we want to use, and then restore it after we're all done
-         * (see bottom of this script).
-         */
-        $defaultTimeZone = date_default_timezone_get();
-        date_default_timezone_set($this->config['settings']['time_zone']);
-
-        // Restore timezone that was set before our code was called
-        date_default_timezone_set($defaultTimeZone);
-
-        return $out;
-
-    }
-}
-
-?>
\ No newline at end of file
index 25af54a..a59bbfe 100644 (file)
@@ -10,7 +10,6 @@
 define('GLM_MEMBERS_CONTACTS_PLUGIN_NAME', 'Gaslight Media Members Database Contacts');
 define('GLM_MEMBERS_CONTACTS_PLUGIN_SHORT_NAME', 'Contacts');
 define('GLM_MEMBERS_CONTACTS_PLUGIN_SLUG', 'glm-member-db-contacts');
-define('GLM_MEMBERS_CONTACTS_PLUGIN_DIR', GLM_MEMBERS_CONTACTS_PLUGIN_SLUG);
 
 // Determine which system we're running on - If not provided, assume PRODUCTION
 $host = getenv('GLM_HOST_ID');
@@ -36,18 +35,16 @@ $WPUploadDir = wp_upload_dir();
 define('GLM_MEMBERS_CONTACTS_SITE_BASE_URL', home_url('/') );
 define('GLM_MEMBERS_CONTACTS_PLUGIN_URL', plugin_dir_url(__FILE__));
 define('GLM_MEMBERS_CONTACTS_PLUGIN_ADMIN_URL', admin_url('admin.php'));
-define('GLM_MEMBERS_CONTACTS_PLUGIN_BASE_URL', WP_PLUGIN_URL.'/'.GLM_MEMBERS_CONTACTS_PLUGIN_DIR);
+define('GLM_MEMBERS_CONTACTS_PLUGIN_BASE_URL', WP_PLUGIN_URL.'/'.GLM_MEMBERS_CONTACTS_PLUGIN_SLUG);
 define('GLM_MEMBERS_CONTACTS_PLUGIN_CURRENT_URL', $urlParts['scheme'].'://'.$urlParts['host'].$pageUri[0]);
-define('GLM_MEMBERS_CONTACTS_PLUGIN_MEDIA_URL', $WPUploadDir['baseurl'].'/'.GLM_MEMBERS_CONTACTS_PLUGIN_DIR);
+define('GLM_MEMBERS_CONTACTS_PLUGIN_MEDIA_URL', $WPUploadDir['baseurl'].'/'.GLM_MEMBERS_CONTACTS_PLUGIN_SLUG);
 
 // Directories
 define('GLM_MEMBERS_CONTACTS_PLUGIN_PATH', dirname(__FILE__));
 define('GLM_MEMBERS_CONTACTS_PLUGIN_DB_SCRIPTS', dirname(__FILE__).'/misc/databaseScripts');
 define('GLM_MEMBERS_CONTACTS_PLUGIN_CLASS_PATH', GLM_MEMBERS_CONTACTS_PLUGIN_PATH.'/classes');
-define('GLM_MEMBERS_CONTACTS_PLUGIN_LIB_PATH', GLM_MEMBERS_CONTACTS_PLUGIN_PATH.'/lib');
-define('GLM_MEMBERS_CONTACTS_PLUGIN_MEDIA_PATH', $WPUploadDir['basedir'].'/'.GLM_MEMBERS_CONTACTS_PLUGIN_DIR);
-define('GLM_MEMBERS_CONTACTS_PLUGIN_IMAGES_PATH', GLM_MEMBERS_CONTACTS_PLUGIN_MEDIA_PATH.'/images');
 define('GLM_MEMBERS_CONTACTS_PLUGIN_CONFIG_PATH', GLM_MEMBERS_CONTACTS_PLUGIN_PATH.'/config');
+define('GLM_MEMBERS_CONTACTS_PLUGIN_SETUP_PATH', GLM_MEMBERS_CONTACTS_PLUGIN_PATH.'/setup');
 
 // Database table prefixes
 global $wpdb;
@@ -57,4 +54,8 @@ define('GLM_MEMBERS_CONTACTS_PLUGIN_DB_PREFIX', $wpdb->prefix.'glm_members_');
 // Parameters related to the Main GLM Member DB plugin - Depending on what's going on these may already defined by the main plugin
 $pluginsPath = str_replace(GLM_MEMBERS_CONTACTS_PLUGIN_SLUG, '', GLM_MEMBERS_CONTACTS_PLUGIN_PATH);
 define('GLM_MEMBERS_CONTACTS_MAIN_PLUGIN_PATH', $pluginsPath.'/glm-member-db');
+define('GLM_MEMBERS_CONTACTS_PLUGIN_LIB_PATH', GLM_MEMBERS_CONTACTS_MAIN_PLUGIN_PATH.'/lib');
+define('GLM_MEMBERS_CONTACTS_PLUGIN_MEDIA_PATH', $WPUploadDir['basedir'].'/'.GLM_MEMBERS_CONTACTS_PLUGIN_SLUG);
+define('GLM_MEMBERS_CONTACTS_PLUGIN_IMAGES_PATH', GLM_MEMBERS_CONTACTS_MAIN_PLUGIN_PATH.'/images');
+
 ?>
index 621e7c5..534ed9f 100644 (file)
@@ -3,7 +3,7 @@
  * Plugin Name: GLM Members Database Contacts
  * Plugin URI: http://www.gaslightmedia.com/
  * Description: Gaslight Media Members Database.
- * Version: 1.0.0
+ * Version: 1.0.43
  * Author: Chuck Scott
  * Author URI: http://www.gaslightmedia.com/
  * License: GPL2
@@ -19,7 +19,7 @@
  * @package glmMembersDatabaseContacts
  * @author Chuck Scott <cscott@gaslightmedia.com>
  * @license http://www.gaslightmedia.com Gaslightmedia
- * @version 1.0.0
+ * @version 1.0.43
  */
 
 /*
@@ -33,8 +33,7 @@
  *  version when there's a change in the database!! Use the
  *  version nunmber of that release for the DB version.
  */
-define('GLM_MEMBERS_CONTACTS_PLUGIN_VERSION', '1.0.0');
-define('GLM_MEMBERS_CONTACTS_PLUGIN_DB_VERSION', '1.0.0');
+define('GLM_MEMBERS_CONTACTS_PLUGIN_VERSION', '1.0.43');
 
 // This is the minimum version of the GLM Members DB plugin require for this plugin.
 define('GLM_MEMBERS_CONTACTS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION', '1.0.43');
@@ -71,9 +70,6 @@ $startupNotices = '';
 // Get standard defined parameters
 require_once('defines.php');
 
-// Get configuration - Getting this from main plugin
-require_once('config.php');
-
 // Required to be able to get user capabilities when being called as a filter from the main plugin
 require_once(ABSPATH . 'wp-includes/pluggable.php');
 
@@ -91,7 +87,9 @@ function glmMembersPluginRequired() {
     ';
 }
 
-// Find out if main GLM Member DB is intalled and active
+/*
+ * Check installation, activation, and version of main Member DB plugin
+ */
 include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
 $plugin_name = 'glm-member-db/glm-member-db.php';
 $is_active = is_plugin_active($plugin_name);
@@ -103,7 +101,7 @@ if ($is_active != '1') {
 }
 
 // Function to generate message regarding main GLM Member DB plugin version is not receint enought to run this add-on
-function glmMembersPluginMinVerRequired() {
+function glmMembersBlankPluginMinVerRequired() {
     echo '
         <div class="error">
             <p>The '.GLM_MEMBERS_CONTACTS_PLUGIN_NAME.' requires that the main GLM Member DB plugin version be no older than '
@@ -113,7 +111,9 @@ function glmMembersPluginMinVerRequired() {
     ';
 }
 
-// Check for minimum GLM Member DB version that will work with this add-on
+/*
+ * Check for Minimum DB version for main Member DB
+ */
 $glmMembersDatabasePluginVersion = get_option('glmMembersDatabasePluginVersion');
 if (version_compare($glmMembersDatabasePluginVersion, GLM_MEMBERS_CONTACTS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION) < 0) {
     add_action( 'admin_notices', 'glmMembersPluginMinVerRequired');
@@ -123,8 +123,7 @@ if (version_compare($glmMembersDatabasePluginVersion, GLM_MEMBERS_CONTACTS_PLUGI
 /*
  * Register this add-on with the main GLM Member DB plugin and get information on all add-ons loaded.
  */
-
-// Register this plugin with glm-member-db
+require_once(GLM_MEMBERS_CONTACTS_PLUGIN_SETUP_PATH.'/validActions.php');
 function glmMembersRegisterContacts($addOns) {
 
     // Add this add-on to the add-ons array
@@ -132,7 +131,8 @@ function glmMembersRegisterContacts($addOns) {
             'dir' => GLM_MEMBERS_CONTACTS_PLUGIN_PATH,
             'name' =>  GLM_MEMBERS_CONTACTS_PLUGIN_NAME,
             'short_name' => GLM_MEMBERS_CONTACTS_PLUGIN_SHORT_NAME,
-            'slug' => GLM_MEMBERS_CONTACTS_PLUGIN_SLUG
+            'slug' => GLM_MEMBERS_CONTACTS_PLUGIN_SLUG,
+            'actions' => $GLOBALS['glmMembersContactsAddOnValidActions']
     );
 
     // Return the array with our data added
@@ -165,19 +165,41 @@ add_filter('glm-member-db-register-addon','glmMembersRegisterContacts', 10, 1);
  }
  register_deactivation_hook(__FILE__, 'glmMembersContactsPluginDeactivate');
 
- /*
-  *
-  * Determine which controller to load
-  *
-  * The first is for displaying notices in another window, possibly for debug output.
-  *
-  */
-if (is_admin()) {
-     require_once (GLM_MEMBERS_CONTACTS_PLUGIN_PATH . '/controllers/admin.php');
-     new glmMembersContactsAdmin($wpdb, $config);
- } else {
-     require_once (GLM_MEMBERS_CONTACTS_PLUGIN_PATH . '/controllers/front.php');
-     new glmMembersContactsFront($wpdb, $config);
- }
+/*
+ * Hooks for testing capabilities provided by this add-on
+ */
+require_once(GLM_MEMBERS_CONTACTS_PLUGIN_SETUP_PATH.'/permissions.php');
+
+/*
+ * Add filter to redirect user to a particular destination on
+ * login based on their roles.
+ */
+
+function my_login_redirect( $redirect_to, $request, $user ) {
+
+    global $user;
+
+    // Do we have a logged in user
+    if ( isset( $user->roles ) && is_array( $user->roles ) ) {
+
+        // If this is a non-contact user or one with a pre-existing non-contact login
+        foreach ($user->roles as $r) {
+            if (substr($r,0,12) != 'glm_members_') {
+                // Go to normal destination for this user
+                return 'htt://www.gaslightmedia.com';
+            }
+        }
+
+        // If we get here, this is a pure contact user, start them at their profile
+        return '/wp-admin/admin.php?page=glm-members-admin-menu-profile';
+
+    }
+
+    // No logged in user - So why is the "login_redirect" filter triggered anyway?
+    return $redirect_to;
+
+}
+add_filter( 'login_redirect', 'my_login_redirect', 10, 3 );
+
 
 ?>
\ No newline at end of file
diff --git a/models/admin/member/contacts.php b/models/admin/member/contacts.php
new file mode 100644 (file)
index 0000000..f13085f
--- /dev/null
@@ -0,0 +1,498 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * Admin Member Contacts List
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+// Load Contacts data abstract
+require_once(GLM_MEMBERS_CONTACTS_PLUGIN_CLASS_PATH.'/data/dataContacts.php');
+
+class GlmMembersAdmin_member_contacts extends GlmDataContacts
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+    /**
+     * Plugin Configuration Data
+     *
+     * @var $config
+     * @access public
+     */
+    public $config;
+    /**
+     * Contacts List
+     *
+     * @var $contacts
+     * @access public
+     */
+    public $contacts = false;
+    /**
+     * Contact Info
+     *
+     * @var $contactInfo
+     * @access public
+     */
+    public $contactInfo = false;
+    /**
+     * Member ID
+     *
+     * @var $memberID
+     * @access public
+     */
+    public $memberID = false;
+    /**
+     * Contact ID
+     *
+     * @var $contactID
+     * @access public
+     */
+    public $contactID = false;
+
+
+    /*
+     * 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;
+        $refType = false;
+        $refTypeName = false;
+        $haveMember = false;
+        $memberData = false;
+        $memberName = false;
+        $haveContacts = false;
+        $newContactExists = false;
+        $misMatchedWpUsers = false;
+        $newContactCreated = false;
+        $usingExistingWPContact = false;
+        $usernameChangedToWP = false;
+        $contactUpdated = false;
+        $filterArchived = false;
+        $filterText = false;
+        $haveFilter = false;
+        $userDeleted = false;
+        $wpUserDeleted = false;
+
+        $validOptions = array(
+            'create',
+            'addNew',
+            'edit',
+            'submit',
+            'delete',
+            'list'
+        );
+
+        if (isset($_REQUEST['member'])) {
+            $this->memberID = $_REQUEST['member']-0;
+        }
+
+        require_once(GLM_MEMBERS_PLUGIN_CLASS_PATH.'/data/dataMembers.php');
+        $Members = new GlmDataMembers($this->wpdb, $this->config);
+        $memberData = $Members->getEntry($this->memberID);
+
+        // Check that we have good member data
+        if (is_array($memberData) && isset($memberData['id']) && $memberData['id'] > 0) {
+
+            $haveMember = true;
+            $memberName = $memberData['name'];
+
+            // If we're adding a new member contact
+            if (isset($_REQUEST['option']) && in_array($_REQUEST['option'], $validOptions)) {
+                $option = $_REQUEST['option'];
+            }
+
+            // Perform selected page option
+            switch($option) {
+
+                case 'create':
+
+                    // Set reference type to Member
+                    $refType = $this->config['ref_type_numb']['Member'];
+                    $refTypeName = $this->config['ref_type'][$refType];
+
+                    $this->contactInfo = $this->newEntry();
+
+                    require_once(GLM_MEMBERS_CONTACTS_PLUGIN_LIB_PATH.'/EasyPassword/EasyPassword.php');
+                    $EasyPassword = new EasyPassword();
+                    $this->contactInfo['fieldData']['password'] = $EasyPassword->generateEasyPassword('firstlast');
+                    break;
+
+                case 'addNew':
+
+                    // Check for new cities being submitted
+                    $this->checkNewCities();
+
+                    // Check for existing contact in Wordpress and Contacts
+                    $contactCheck = $this->checkContact($_REQUEST['email'], $_REQUEST['username']);
+
+                    // If there's already a contact with this E-Mail address, don't create the contact
+                    if ($contactCheck['contactsEmail'] || $contactCheck['contactsUsername']) {
+                        $newContactExists = true;
+                        break;
+                    }
+
+                    // If there is already a WordPress user with the requested Email address and a different user with the requeted Username
+                    if ($contactCheck['wordpressEmail'] && $contactCheck['wordpressLogin']
+                        && $contactCheck['wpUserEmail']->ID != $contactCheck['wpUserLogin']->ID) {
+                        $misMatchedWpUsers = true;
+                        break;
+                    }
+
+                    // Try to insert the new contact
+                    $this->contactInfo = $this->insertEntry();
+
+
+                    // If that was successful
+                    if ($this->contactInfo['status']) {
+
+                        // If there's an existing WordPress user matching the E-Mail address but that has a different username
+                        if ($contactCheck['wordpressEmail']
+                            && $contactCheck['wpUserEmail']->data->user_login != $this->contactInfo['fieldData']['username']) {
+
+                            // Change the contact username to match the Wordpress username
+                            $this->wpdb->query("
+                                UPDATE ".GLM_MEMBERS_PLUGIN_DB_PREFIX . "contacts
+                                   SET username = '".$contactCheck['wpUserEmail']->data->user_login."'
+                                 WHERE id = ".$this->contactInfo['fieldData']['id'].";
+                            ");
+                            $usernameChangedToWP = true;
+
+                        }
+
+                        // Determine the Worpress Role to be used
+                        $roleNumb = $this->contactInfo['fieldData']['contact_role']['value'];
+                        $wpRole = $this->config['contact_role_wordpress'][$roleNumb];
+
+                        // If there's an existing WordPress user we're going to use
+                        if ($contactCheck['wordpressEmail']) {
+
+                            // Add appropriate user role
+                            $wpUser = new WP_User($contactCheck['wpUserEmail']->ID);
+                            $wpUser->add_role($wpRole);
+
+                            $usingExistingWPContact = true;
+
+                            $userID = $contactCheck['wpUserEmail']->ID;
+
+                        // Otherwise
+                        } else {
+
+                            // Create a new Wordpress user
+                            $userID = wp_insert_user(
+                                array(
+                                    'user_email' => $this->contactInfo['fieldData']['email'],
+                                    'user_login' => $this->contactInfo['fieldData']['username'],
+                                    'user_pass' => trim($_REQUEST['password']),
+                                    'first_name' => $this->contactInfo['fieldData']['fname'],
+                                    'last_name' => $this->contactInfo['fieldData']['lname'],
+                                    'role' => $wpRole
+                                )
+                            );
+
+                        }
+
+                        // Get the updated user information
+                        $this->contactInfo = $this->editEntry($this->contactInfo['fieldData']['id']);
+
+                        $newContactCreated = true;
+
+                        // Store the contact ID, user entityType, and entityID into user meta data
+                        update_user_meta($userID, 'glmMembersContactID', $this->contactInfo['fieldData']['id']);
+
+                        break;
+                    }
+
+                    // Need to retry so set option to create, use unencrypted password, and get ref_type again
+                    $option = 'create';
+                    $this->contactInfo['fieldData']['password'] = $_REQUEST['password'];
+                    $refType = $_REQUEST['ref_type'];
+                    $refTypeName = $this->config['ref_type'][$refType];
+
+                    // If addNew was unsuccessful, fall through to edit
+
+                case 'edit':
+
+                    // Get contact ID to edit
+                    if (isset($_REQUEST['contact']) && ($_REQUEST['contact'] -0) > 0) {
+
+                        // We have a contact ID, so try to edit
+                        $this->contactID = $_REQUEST['contact'] - 0;
+                        $this->contactInfo = $this->editEntry($this->contactID);
+
+                        // If the contact wasn't found, then set ID to false
+                        if (!$this->contactInfo['status']) {
+                            $this->contactID = false;
+                        }
+
+                    }
+
+                    break;
+
+                case 'submit':
+
+                    // Check for new cities being submitted
+                    $this->checkNewCities();
+
+                    // Get current role set in the contacts record along with the matching WP role slug
+                    $this->contactID = ($_REQUEST['contact']-0);
+
+                    $savedContactRole = $this->getWpRole($this->contactID);
+
+                    $this->contactInfo = $this->updateEntry($this->contactID);
+
+                    if ($this->contactInfo['status']) {
+                        $this->contactInfo = $this->editEntry(($_REQUEST['id']-0));
+                        $contactUpdated = true;
+
+                        // Check for password changes and update Wordpress user
+                        if (trim($_REQUEST['password']) != '') {
+
+                            // Get the wordpress user ID
+                            $wpUser = get_user_by('email', $this->contactInfo['fieldData']['email']);
+
+                            // If we got a good user, set the new password
+                            if ($wpUser) {
+                                wp_set_password($_REQUEST['password'], $wpUser->ID);
+                            }
+
+                        }
+
+                        // Determine the Worpress Role to be used
+                        $roleNumb = $this->contactInfo['fieldData']['contact_role']['value'];
+                        $wpRole = $this->config['contact_role_wordpress'][$roleNumb];
+
+                        // If there's a role change, update the user role for WordPress
+                        if ($wpRole != $savedContactRole['wpRole']) {
+                            $contactCheck = $this->checkContact($this->contactInfo['fieldData']['email']);
+                            $wpUser = new WP_User($contactCheck['wpUserEmail']->ID);
+                            $wpUser->remove_role($savedContactRole['wpRole']);
+                            $wpUser->add_role($wpRole);
+                        }
+
+                    }
+
+                    $option = 'edit';
+
+                    break;
+
+                case 'delete':
+
+
+                    // Delete the current entry without further confirmation - pop-up should be confirmation enough.
+                    $oldContactInfo = $this->deleteEntry(($_REQUEST['contact']-0), true);
+                    $userDeleted = true;
+
+                    // Get the wordpress user ID
+                    $wpUser = get_user_by('email', $oldContactInfo['email']);
+
+                    // Check for other roles assigned to this user and remove our roles
+                    $userHasOtherRole = false;
+                    foreach ($wpUser->roles as $r) {
+
+                        // Is this role not one of ours?
+                        if (!in_array($r, $this->config['contact_role_wordpress'])) {
+
+                            // Apparently not, so we need to keep the Wordpress user
+                            $userHasOtherRole = true;
+
+                        //Otherwise, this is one of our roles so we should remove it just in case the Wordpress user isn't deleted
+                        } else {
+
+                            // Remove this role from our user
+                            $wpUser->remove_role($r);
+
+                        }
+
+                    }
+
+                    // If the user doesn't have a role other than our members contact roles
+                    if (!$userHasOtherRole) {
+
+                        // Delete the wordpress user
+                        wp_delete_user($wpUser->ID);
+                        $wpUserDeleted = true;
+
+                    }
+
+                    // Return to list by falling through here.
+                    // break;
+
+                default:
+
+                    // Make sure option is set to list
+                    $option = 'list';
+
+                    // Only list member contacts for the selected member
+                    $where = "T.ref_type = ".$this->config['ref_type_numb']['Member'].' AND T.ref_dest = '.$this->memberID;
+
+                    // Filter by text string supplied
+                    if (isset($_REQUEST['filterText'])) {
+                        $filterText = esc_sql($_REQUEST['filterText']);
+                        $where .= " AND (
+                            T.lname LIKE '%$filterText%' OR
+                            T.fname LIKE '%$filterText%' OR
+                            T.org LIKE '%$filterText%' OR
+                            T.descr LIKE '%$filterText%'
+                        )";
+                        $haveFilter = true;
+                    }
+
+                    // Check if this is a request to show archived contacts
+                    if (!isset($_REQUEST['filterArchived'])) {
+                        $where .= " AND T.access != ".$this->config['access_numb']['Archived'];
+                        $filterArchived = false;
+                    } else {
+                        $filterArchived = true;
+                        $haveFilter = true;
+                    }
+
+                    // Try to get list of contacts
+                    $this->contacts = $this->getList($where);
+                    if ($this->contacts !== false) {
+                        if (count($this->contacts) > 0) {
+                            $haveContacts = true;
+                        }
+                    }
+                    break;
+            }
+
+            // If the option is "edit" don't let lower-level users assign privileges above the user's pay grade
+            if ($option == 'edit' && $this->config['loggedInUser']['contactUser']) {
+
+                // If this is an Entity Manager or lower user, then remove the "MembersManger" role selection
+                if ($this->config['loggedInUser']['contactUser']['role'] >= $this->config['contact_role_numb']['EntityManager']) {
+                    unset($this->contactInfo['fieldData']['contact_role']['list'][$this->config['contact_role_numb']['MembersManager']]);
+                }
+
+            }
+
+        } // if haveMember
+
+
+        // Compile template data
+        $templateData = array(
+            'option' => $option,
+            'haveMember' => $haveMember,
+            'memberID' => $this->memberID,
+            'memberData' => $memberData,
+            'memberName' => $memberName,
+            'refType' => $refType,
+            'refTypeName' => $refTypeName,
+            'haveContacts' => $haveContacts,
+            'contacts' => $this->contacts,
+            'contactID' => $this->contactID,
+            'contactInfo' => $this->contactInfo,
+            'newContactExists' => $newContactExists,
+            'misMatchedWpUsers' => $misMatchedWpUsers,
+            'usernameChangedToWP' => $usernameChangedToWP,
+            'newContactCreated' => $newContactCreated,
+            'usingExistingWPContact' => $usingExistingWPContact,
+            'contactUpdated' => $contactUpdated,
+            'filterArchived' => $filterArchived,
+            'filterText' => $filterText,
+            'haveFilter' => $haveFilter,
+            'userDeleted' => $userDeleted,
+            'wpUserDeleted' => $wpUserDeleted
+        );
+
+        // Return status, any suggested view, and any data to controller
+        return array(
+                'status' => true,
+                'modelRedirect' => false,
+                'view' => 'admin/member/contacts.html',
+                'data' => $templateData
+        );
+
+    }
+
+    /*
+     * Check for new Cities being submitted
+     *
+     * @return void
+     */
+    public function checkNewCities()
+    {
+
+        // If we have a member ID and this was a submission with a new city (id < 0)
+        if ($this->contactID && isset($_REQUEST['city']) && $_REQUEST['city'] == -1 && isset($_REQUEST['newCityName']) && trim($_REQUEST['newCityName']) != '') {
+
+            // Clean up city name
+            $cName = trim(filter_var($_REQUEST['newCityName']));
+
+            // Try to add the city
+            require_once(GLM_MEMBERS_CONTACTS_PLUGIN_CLASS_PATH.'/data/dataCities.php');
+            $Cities = new GlmDataCities($this->wpdb, $this->config);
+            $cID = $Cities->addCity($cName);
+
+            // If we got a city id back
+            if (is_int($cID) && $cID > 0) {
+
+                // Update the city selected for this memberInfo record
+                $sql = "
+                        UPDATE ".GLM_MEMBERS_PLUGIN_DB_PREFIX."contacts
+                            SET city = $cID
+                            WHERE id = ".$this->contactID."
+                            ;";
+                $this->wpdb->query($sql);
+
+                // Update submitted city value to use the new ID
+                $_REQUEST['city'] = $cID;
+
+            }
+        }
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/models/admin/members/contacts.php b/models/admin/members/contacts.php
new file mode 100644 (file)
index 0000000..35d82f3
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+
+/**
+ * Gaslight Media Members Database
+ * Admin Full Contacts List
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+// Load Contacts data abstract
+require_once(GLM_MEMBERS_CONTACTS_PLUGIN_CLASS_PATH.'/data/dataContacts.php');
+
+/*
+ * This model is called when the "Shortcodes" menu is selected
+ *
+ */
+class GlmMembersAdmin_members_contacts extends GlmDataContacts
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+    /**
+     * Plugin Configuration Data
+     *
+     * @var $config
+     * @access public
+     */
+    public $config;
+    /**
+     * Contacts List
+     *
+     * @var $contacts
+     * @access public
+     */
+    public $contacts;
+
+    /*
+     * 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) {
+
+        $haveContacts = false;
+        $filterArchived = false;
+        $filterText = false;
+        $haveFilter = false;
+
+            // Only list member contacts for the selected member
+        $where = "true";
+
+        // Filter by text string supplied
+        if (isset($_REQUEST['filterText'])) {
+            $filterText = esc_sql($_REQUEST['filterText']);
+            $where .= " AND (
+                T.lname LIKE '%$filterText%' OR
+                T.fname LIKE '%$filterText%' OR
+                T.org LIKE '%$filterText%' OR
+                T.descr LIKE '%$filterText%'
+            )";
+            $haveFilter = true;
+        }
+
+        // Check if this is a request to show archived contacts
+        if (!isset($_REQUEST['filterArchived'])) {
+            $where .= " AND T.access != ".$this->config['access_numb']['Archived'];
+            $filterArchived = false;
+        } else {
+            $filterArchived = true;
+            $haveFilter = true;
+        }
+
+        // Get list of contacts
+        $this->contacts = $this->getList($where);
+
+        if ($this->contacts !== false) {
+            if (count($this->contacts) > 0) {
+                $haveContacts = true;
+            }
+        }
+
+        // Compile template data
+        $templateData = array(
+            'haveContacts' => $haveContacts,
+            'contacts' => $this->contacts,
+            'filterArchived' => $filterArchived,
+            'filterText' => $filterText,
+            'haveFilter' => $haveFilter
+        );
+
+        // Return status, any suggested view, and any data to controller
+        return array(
+                'status' => true,
+                'modelRedirect' => false,
+                'view' => 'admin/members/contacts.html',
+                'data' => $templateData
+        );
+
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/models/admin/profile/index.php b/models/admin/profile/index.php
new file mode 100644 (file)
index 0000000..0704d3a
--- /dev/null
@@ -0,0 +1,240 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * Admin Member My Profile
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  index.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+// Load Contacts data abstract
+require_once(GLM_MEMBERS_CONTACTS_PLUGIN_CLASS_PATH.'/data/dataContacts.php');
+
+class GlmMembersAdmin_profile_index extends GlmDataContacts
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+    /**
+     * Plugin Configuration Data
+     *
+     * @var $config
+     * @access public
+     */
+    public $config;
+    /**
+     * Contact Info
+     *
+     * @var $contactInfo
+     * @access public
+     */
+    public $contactInfo = false;
+    /**
+     * Member ID
+     *
+     * @var $memberID
+     * @access public
+     */
+    public $memberID = false;
+    /**
+     * Contact ID
+     *
+     * @var $contactID
+     * @access public
+     */
+    public $contactID = false;
+
+
+    /*
+     * 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 the Contacts data class
+         *
+         * Note, the third parameter is a flag that indicates to the Contacts
+         * data class that it should flag a group of fields as 'view_only'.
+         */
+        parent::__construct(false, false, true);
+
+
+    }
+
+    public function modelAction($actionData = false)
+    {
+
+        $contactUpdated = false;
+
+        $validOptions = array(
+            'edit',
+            'submit'
+        );
+
+        // Check that user is a contact user
+        if ($this->config['loggedInUser']['contactUser']) {
+
+            // Get contact user ID and validate it as positive Integer
+            $this->contactID = ($this->config['loggedInUser']['contactUser']['ID'] - 0);
+            if ($this->contactID > 0) {
+
+                // Check for valid option
+                $option = 'edit';
+                if (isset($_REQUEST['option']) && in_array($_REQUEST['option'], $validOptions)) {
+                    $option = $_REQUEST['option'];
+                }
+
+
+                // Perform selected page option
+                switch($option) {
+
+                    case 'submit':
+
+                        // Check for new cities being submitted
+                        $this->checkNewCities();
+
+                        // Process the profile update submission
+                        $this->contactInfo = $this->updateEntry($this->contactID);
+
+                        // If the submission was a success
+                        if ($this->contactInfo['status']) {
+
+                            $contactUpdated = true;
+
+                            // Check for password changes and update Wordpress user
+                            if (trim($_REQUEST['password']) != '') {
+
+                                // Get the wordpress user ID
+                                $wpUserID = ($this->config['loggedInUser']['wpUser']['ID'] - 0);
+
+                                // If we got a good user, set the new password
+                                if ($wpUser > 0) {
+                                    wp_set_password($_REQUEST['password'], $wpUserID);
+                                }
+
+                            }
+
+                        $option = 'edit';
+
+
+                        }
+
+                        break;
+
+                    default:
+                    case 'edit':
+
+                        $this->contactInfo = $this->editEntry($this->contactID);
+
+                        // If the contact wasn't found, then set ID to false
+                        if (!$this->contactInfo['status']) {
+                            $this->contactID = false;
+                        }
+
+                        break;
+
+                }
+
+            } // have contact ID
+
+        } // is contact user
+
+
+        // Compile template data
+        $templateData = array(
+            'option' => $option,
+            'contactID' => $this->contactID,
+            'contactInfo' => $this->contactInfo,
+            'contactUpdated' => $contactUpdated
+        );
+
+        // Return status, any suggested view, and any data to controller
+        return array(
+                'status' => true,
+                'modelRedirect' => false,
+                'view' => 'admin/profile/index.html',
+                'data' => $templateData
+        );
+
+    }
+
+    /*
+     * Check for new Cities being submitted
+     *
+     * @return void
+     */
+    public function checkNewCities()
+    {
+
+        // If we have a member ID and this was a submission with a new city (id < 0)
+        if ($this->contactID && isset($_REQUEST['city']) && $_REQUEST['city'] == -1 && isset($_REQUEST['newCityName']) && trim($_REQUEST['newCityName']) != '') {
+
+            // Clean up city name
+            $cName = trim(filter_var($_REQUEST['newCityName']));
+
+            // Try to add the city
+            require_once(GLM_MEMBERS_CONTACTS_PLUGIN_CLASS_PATH.'/data/dataCities.php');
+            $Cities = new GlmDataCities($this->wpdb, $this->config);
+            $cID = $Cities->addCity($cName);
+
+            // If we got a city id back
+            if (is_int($cID) && $cID > 0) {
+
+                // Update the city selected for this memberInfo record
+                $sql = "
+                        UPDATE ".GLM_MEMBERS_PLUGIN_DB_PREFIX."contacts
+                            SET city = $cID
+                            WHERE id = ".$this->contactID."
+                            ;";
+                $this->wpdb->query($sql);
+
+                // Update submitted city value to use the new ID
+                $_REQUEST['city'] = $cID;
+
+            }
+        }
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/models/admin/sample/index.php b/models/admin/sample/index.php
new file mode 100644 (file)
index 0000000..86289ad
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * Gaslight Media Members Database
+ * Admin Sample
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * This model is called when the "Shortcodes" menu is selected
+ *
+ */
+class GlmMembersAdmin_sample_index
+{
+
+    /**
+     * 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;
+
+    }
+
+    public function modelAction($actionData = false) {
+
+        // Return status, any suggested view, and any data to controller
+        return array(
+                'status' => true,
+                'modelRedirect' => false,
+                'view' => 'admin/sample/index.html',
+                'data' => false
+        );
+
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/setup/adminMenus.php b/setup/adminMenus.php
new file mode 100644 (file)
index 0000000..e735a94
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * Member Contact Add-On Admin Menus
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * Added menus or sub-menus examples
+ *
+ * add_submenu_page(
+ *     'glm-members-admin-menu-members',                   // Parent slug
+ *     'Sample',                                           // Page title
+ *     'Sample',                                           // Menu Title
+ *     'glm_members_edit',                                 // Capability required
+ *     'glm-members-admin-menu-sample',                    // Menu slug
+ *     function() {$this->controller('sample');}
+ * );
+ *
+ * If creating a main menu item with add_menu_page(), please document
+ * that structure here.
+ *
+ */
+
+// If a contact is logged in (ownEntity isn't false), add Contact Profile menu item
+if ($this->config['loggedInUser']['contactUser']) {
+    add_submenu_page(
+        $mainMenuSlug,
+        'My Profile',
+        'My Profile',
+        'glm_members_edit_my_contact_info',
+        'glm-members-admin-menu-profile',
+        function() {$this->controller('profile');}
+    );
+}
+
+?>
diff --git a/setup/adminTabs.php b/setup/adminTabs.php
new file mode 100644 (file)
index 0000000..410389f
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * Member Contact Add-On Admin Tabs
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * To add a new tab to an existing Member DB page use a blick
+ * like this and replace the {} parameters.
+ *
+ * add_filter('glm-member-db-add-tab-for-{menu name}',
+ *     function($addOnTabs) {
+ *         $newTabs = array(
+ *             array(
+ *                 'text' => '{text for display on tab}',
+ *                 'menu' => '{menu name}',
+ *                 'action' => '{action to perform}'
+ *             )
+ *         );
+ *         $addOnTabs = array_merge($addOnTabs, $newTabs);
+ *         return $addOnTabs;
+ *     }
+ * );
+ *
+ */
+
+add_filter('glm-member-db-add-tab-for-members',
+    function($addOnTabs) {
+        $newTabs = array(
+            array(
+                'text' => 'Contacts List',
+                'menu' => 'members',
+                'action' => 'contacts'
+            )
+        );
+        $addOnTabs = array_merge($addOnTabs, $newTabs);
+        return $addOnTabs;
+    }
+);
+
+if (apply_filters('glm_members_permit_admin_member_contacts_tab', true)) {
+    add_filter('glm-member-db-add-tab-for-member',
+        function($addOnTabs) {
+            $newTabs = array(
+                array(
+                        'text' => 'Member Contacts',
+                        'menu' => 'member',
+                        'action' => 'contacts'
+                )
+            );
+            $addOnTabs = array_merge($addOnTabs, $newTabs);
+            return $addOnTabs;
+        }
+    );
+}
+
+?>
\ No newline at end of file
diff --git a/setup/permissions.php b/setup/permissions.php
new file mode 100644 (file)
index 0000000..b8ce13a
--- /dev/null
@@ -0,0 +1,262 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * Member Contact Add-On Permissions
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  permissions.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * Use hook to main plugin to supply information on the logged in user to
+ * be stored in the config data. This should be an array of relevant information
+ * that would generally be used by this add-on, but to which other add-ons
+ * may need to refer.
+ */
+add_filter('glm_members_current_logged_in_user',
+    function($loggedInUser) {
+
+        global $wpdb;
+
+        // Add default of no current contact user
+        $loggedInUser['contactUser'] = false;
+
+        // If no wordpress user is logged in, then no point checking for a contact user
+        if (!$loggedInUser['wpUser']) {
+            return $loggedInUser;
+        }
+
+        // Get contact ID from user meta data, if none then not a contact user, return false
+        $wpUserID = $loggedInUser['wpUser']['ID'];
+        $contactID = get_user_meta($wpUserID, 'glmMembersContactID', true);
+        if ($contactID == '') {
+            return $loggedInUser;
+        }
+
+        // Try to get the matching contact data
+        $contactInfo = $wpdb->get_row("SELECT * FROM ".GLM_MEMBERS_CONTACTS_PLUGIN_DB_PREFIX . "contacts WHERE id = $contactID;");
+
+        // If contact is not active, then return false - should not be logged in
+        if (!$contactInfo->active) {
+            return false;
+        }
+
+        // Return array with base data on this contact that might be needed by this add-on
+        $loggedInUser['contactUser'] = array(
+            'ID' => $contactID,
+            'fname' => $contactInfo->fname,
+            'lname' => $contactInfo->lname,
+            'email' => $contactInfo->email,
+            'ref_type' => $contactInfo->ref_type,
+            'ref_dest' => $contactInfo->ref_dest,
+            'role' => $contactInfo->contact_role,
+            'access' => $contactInfo->access
+        );
+        return $loggedInUser;
+    }
+);
+
+// Provide hook with any member ID to which this user should be locked.
+add_filter('glm_members_locked_to_member_id',
+    function($memberID) {
+
+        global $config;
+        $user = $config['loggedInUser']['contactUser'];
+
+        // If there's a logged in contact user and they are ref_type "Member", then return that member ID
+        if ($user && $user['ref_type'] == $config['ref_type_numb']['Member']) {
+            return $user['ref_dest'];
+        }
+
+        // Otherwise, return any member ID supplied by the hook.
+        return $memberID;
+    }
+);
+
+
+/*
+ * Below are permission checks for various specific things in this add-on and
+ * elsewhere in the Member DB main plugin and add-ons.
+ *
+ * Each location where a permission might be required has an apply_filters()
+ * hook with a tag name that includes the plugin or add-on name, the menu,
+ * the action, and a name for the specific thing that needs permissions.
+ *
+ * This can be included in code or in a Smarty template used in these plugins.
+ * For example, to check permissions for the main Members menu and it's "index"
+ * action to see if a member search is permitted, the template includes the
+ * following code...
+ *
+ * {if $membersList && apply_filters('glm_members_permit_admin_members_index_member_search', true)}
+ *      --- some template output ---
+ * {/if}
+ *
+ * In the case above, it's also checking to see if the members list even exists
+ * before checking the permissions. The default value of "true" in the hook ensures
+ * that the permission is granted if nothing has linked into the hook to say otherwise.
+ *
+ * Note that each add_filter() below first checks if the permission has already
+ * been retracted by prior hook. This requires all that are attached to the hook
+ * to permit the action.
+ *
+ * Of course any of these may test more than one capability if that's desired.
+ */
+
+// glm-member-db, Menu "Members"
+add_filter('glm_members_menu_members',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_view_any_member');
+    }
+);
+
+// glm-member-db, Menu "Member", use glm_members_menu_member
+
+// glm-member-db, Menu "Configure", use glm_members_menu_configure
+
+// glm-member-db, Menu "Management", use glm_members_menu_mangement
+
+// glm-member-db, Menu "Shortcodes", use glm_members_menu_shortcodes
+
+
+// glm-member-db, views/admin/members/index.html, Display config data warnings
+add_filter('glm_members_permit_admin_members_index_member_config_warning',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_view_any_member');
+    }
+);
+
+// glm-member-db, views/members/index.html, Display Add New Member Button
+add_filter('glm_members_permit_admin_members_index_add_member',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_edit_any_member');
+    }
+);
+
+// glm-member-db, view/member/index.html, Display Add New Member Information Version button
+add_filter('glm_members_permit_admin_member_index_add_member_info_version',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_edit_any_member') || current_user_can('glm_members_edit_my_member');
+    }
+);
+
+// glm-member-db, view/member/index.html, Display form to edit base member data, otherwise show it.
+add_filter('glm_members_permit_admin_member_index_edit_member',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_edit_any_member');
+    }
+);
+
+// glm-member-db, view/member/index.html, Display link to view/edit member information
+add_filter('glm_members_permit_admin_member_index_view_member_info_version',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_view_any_member') || current_user_can('glm_members_view_my_entity_info');
+    }
+);
+
+// glm-member-db, view/member/index.html, Display Clone and Activate buttons for Member Information
+add_filter('glm_members_permit_admin_member_index_clone_activate_info_version',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_edit_any_member') || current_user_can('glm_members_edit_my_member');
+    }
+);
+
+// glm-member-db, view/member/index.html, Display Contacts tab
+add_filter('glm_members_permit_admin_member_contacts_tab',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_view_any_member') || current_user_can('glm_members_view_my_member');
+    }
+);
+
+// glm-member-db, view/member/contacts.html, Display Contacts tab
+add_filter('glm_members_permit_admin_member_contacts_add_contact',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_edit_any_member') || current_user_can('glm_members_edit_my_member');
+    }
+);
+
+// glm-member-db, view/member/contacts.html, View Contact data
+add_filter('glm_members_permit_admin_member_contacts_view_contact',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_view_any_member') || current_user_can('glm_members_view_my_member');
+    }
+);
+
+// glm-member-db, view/member/contacts.html, Edit Contact data
+add_filter('glm_members_permit_admin_member_contacts_edit_contact',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_edit_any_member') || current_user_can('glm_members_edit_my_member');
+    }
+);
+
+// glm-member-db, view/dashboardWidget.html, Display members search and list
+add_filter('glm_members_permit_admin_widget_members',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_view_any_member') || current_user_can('glm_members_edit_my_member');
+    }
+);
+
+// glm-member-db, view/dashboardWidget.html, Display warnings
+add_filter('glm_members_permit_admin_widget_warnings',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_configure');
+    }
+);
+
+// glm-member-db, view/dashboardWidget.html, Display pending member info needing attention
+add_filter('glm_members_permit_admin_widget_pending_info',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_edit_any_member');
+    }
+);
+
+// glm-member-db, view/member/index.html, Display inactive member information in member info list
+add_filter('glm_members_permit_admin_member_index_list_inactive_info',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_moderate_my_member_info')
+            || current_user_can('glm_members_edit_my_member')
+            || current_user_can('glm_members_edit_any_member')
+            || current_user_can('glm_members_delete_my_entity_info')
+        ;
+    }
+);
+
+// glm-member-db, view/member/memberInfo.html, Permit editing of member information
+add_filter('glm_members_permit_admin_member_info_edit',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_edit_my_member') || current_user_can('glm_members_edit_my_entity');
+    }
+);
+
+// glm-member-db, view/admin/profile/index.html, Permit editing of own contact profile
+add_filter('glm_members_permit_admin_profile_index_edit_profile',
+    function($permit) {
+        if (!$permit) { return false; }
+        return current_user_can('glm_members_edit_my_contact_info');
+    }
+);
+
+
+
+
diff --git a/setup/rolesAndCapabilities.php b/setup/rolesAndCapabilities.php
new file mode 100644 (file)
index 0000000..045ea30
--- /dev/null
@@ -0,0 +1,334 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * Member Contact Set Add-On Roles and Permissions
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  rolesAndPermissions.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/**
+ * NOTE: This file is only included in the activate.php process.
+ *       It is not regularly used during operation.
+ */
+
+
+/*
+ * Some maintenance items first
+ */
+
+// *** TEMPORARY TO REMOVE OLD ROLSES
+remove_role('glm_own_member_manager');
+remove_role('glm_own_entity_manager');
+remove_role('glm_member_contact');
+remove_role('glm_member_restricted_contact');
+remove_role('glm_members_own_member_manager');
+
+/*
+// Un-comment to fully reset all contact roles
+remove_role('glm_members_manager');
+remove_role('glm_members_own_entity_manager');
+remove_role('glm_members_member_contact');
+remove_role('glm_members_restricted_contact');
+
+// Un-comment the following lines to reset all contacts capabilities to default
+$this->deleteRoleCapability('glm_members_login');
+$this->deleteRoleCapability('glm_members_add_new_member');
+$this->deleteRoleCapability('glm_members_view_any_member');
+$this->deleteRoleCapability('glm_members_edit_any_member');
+$this->deleteRoleCapability('glm_members_delete_any_member');
+$this->deleteRoleCapability('glm_members_moderate_any_member_info');
+$this->deleteRoleCapability('glm_members_view_my_member');
+$this->deleteRoleCapability('glm_members_edit_my_member');
+$this->deleteRoleCapability('glm_members_delete_my_member_info');
+$this->deleteRoleCapability('glm_members_moderate_my_member_info');
+$this->deleteRoleCapability('glm_members_view_my_entity');
+$this->deleteRoleCapability('glm_members_edit_my_entity');
+$this->deleteRoleCapability('glm_members_delete_my_entity_info');
+$this->deleteRoleCapability('glm_members_moderate_my_entity_info');
+$this->deleteRoleCapability('glm_members_view_my_entity_info');
+$this->deleteRoleCapability('glm_members_edit_my_contact_info');
+$this->deleteRoleCapability('glm_members_my_edits_moderated');
+*/
+
+/*
+ * Add contacts roles and set capabilities added in main member DB plugin
+ */
+
+// Members Manager - Full control of all members and their data
+add_role(
+    'glm_members_manager',
+    'GLM Members Manager',
+    array(
+        'read' => true,
+        'glm_members_main_menu' => true,
+        'glm_members_member' => true,
+        'glm_members_configure' => true,
+        'glm_members_management' => false,
+        'glm_members_shortcodes' => true,
+        'glm_members_widget' => true
+    )
+);
+
+// Own Entity Manager - Full control of own entity (location, facility, activity, ...)
+add_role(
+    'glm_members_own_entity_manager',
+    'GLM Own Entity Manager',
+    array(
+        'read' => true,
+        'glm_members_main_menu' => true,
+        'glm_members_member' => true,
+        'glm_members_configure' => false,
+        'glm_members_management' => false,
+        'glm_members_shortcodes' => false,
+        'glm_members_widget' => true
+    )
+);
+
+// Member Contact - Standard contact for own member, location, facility, ... - no edit of member data
+add_role(
+    'glm_members_member_contact',
+    'GLM Member Contact',
+    array(
+        'read' => true,
+        'glm_members_main_menu' => true,
+        'glm_members_member' => false,
+        'glm_members_configure' => false,
+        'glm_members_management' => false,
+        'glm_members_shortcodes' => false,
+        'glm_members_widget' => false
+    )
+);
+
+// Restricted Member Contact - No login capability - capabilities aren't used
+add_role(
+    'glm_members_restricted_contact',
+    'GLM Member Restricted Contact',
+    array(
+        'read' => true,
+        'glm_members_main_menu' => false,
+        'glm_members_member' => false,
+        'glm_members_configure' => false,
+        'glm_members_management' => false,
+        'glm_members_shortcodes' => false,
+        'glm_members_widget' => false
+    )
+);
+
+/*
+ * Add contacts capabilities
+ *
+ * Note that the glm_members_management capability is created by the main Member DB plugin
+ */
+
+// May log in through members only area
+$this->addRoleCapability(
+    'glm_members_login',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => true,
+        'glm_members_member_contact' => true,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May add new members
+$this->addRoleCapability(
+    'glm_members_add_new_member',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => false,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May add view information for any member
+$this->addRoleCapability(
+    'glm_members_view_any_member',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => false,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May edit information for any member
+$this->addRoleCapability(
+    'glm_members_edit_any_member',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => false,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May delete any member
+$this->addRoleCapability(
+    'glm_members_delete_any_member',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => false,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May moderate any member
+$this->addRoleCapability(
+    'glm_members_moderate_any_member_info',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => false,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May view information for my own member
+$this->addRoleCapability(
+    'glm_members_view_my_member',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => true,
+        'glm_members_member_contact' => true,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May edit any information for my own member
+$this->addRoleCapability(
+    'glm_members_edit_my_member',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => true,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May delete information for my own member
+$this->addRoleCapability(
+    'glm_members_delete_my_member_info',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => false,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May moderate any information for my own member
+$this->addRoleCapability(
+    'glm_members_moderate_my_member_info',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => false,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May view information for my own entity (i.e. location, facility, activity, ...)
+$this->addRoleCapability(
+    'glm_members_view_my_entity',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => true,
+        'glm_members_member_contact' => true,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May edit any information for my own entity (i.e. location, facility, activity, ...)
+$this->addRoleCapability(
+    'glm_members_edit_my_entity',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => true,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May delete any information for my own entity (i.e. location, facility, activity, ...)
+$this->addRoleCapability(
+    'glm_members_delete_my_entity_info',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => true,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May moderate any information for my own entity (i.e. location, facility, activity, ...)
+$this->addRoleCapability(
+    'glm_members_moderate_my_entity_info',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => true,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May view any information for my own entity (i.e. location, facility, activity, ...)
+$this->addRoleCapability(
+    'glm_members_view_my_entity_info',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => true,
+        'glm_members_member_contact' => true,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// May edit own contact information
+$this->addRoleCapability(
+    'glm_members_edit_my_contact_info',
+    array(
+        'administrator' => true,
+        'glm_members_manager' => true,
+        'glm_members_own_entity_manager' => true,
+        'glm_members_member_contact' => true,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+// User's changes are moderated
+$this->addRoleCapability(
+    'glm_members_my_edits_moderated',
+    array(
+        'administrator' => false,
+        'glm_members_manager' => false,
+        'glm_members_own_entity_manager' => false,
+        'glm_members_member_contact' => false,
+        'glm_members_restricted_contact' => false
+    )
+);
+
+?>
\ No newline at end of file
diff --git a/setup/validActions.php b/setup/validActions.php
new file mode 100644 (file)
index 0000000..8af4d47
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * Member Contact Add-On Valid Actions
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * Array of valid menu items and actions.
+ *
+ * The higher level elements are valid menu items. These correlate to
+ * actual menu or sub menu items that are hooks back to this controller
+ * class.
+ *
+ * The lower level items below each menu item are actions that may be specified
+ * by a "glmMembersAction" form field.
+ *
+ * The string after the action is the slug of the plugin where the model/view
+ * is to perform that action.
+ *
+ * This array is integrated into the valid actions array in the main GLM Member
+ * DB plugin when this plugin registers itself.
+ */
+
+$glmMembersContactsAddOnValidActions = array(
+    'adminActions' => array(
+        'members' => array(
+            'contacts' => GLM_MEMBERS_CONTACTS_PLUGIN_SLUG
+        ),
+        'member' => array(
+            'contacts' => GLM_MEMBERS_CONTACTS_PLUGIN_SLUG
+        ),
+        'profile' => array(
+            'index' => GLM_MEMBERS_CONTACTS_PLUGIN_SLUG
+        )
+    ),
+    'frontActions' => array(
+    )
+);
+
+
+?>
\ No newline at end of file
index 0702743..9e9bbc6 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-die('uninstall');
+die('uninstall not configured - See plugin uninstall.php script!');
 /**
  * Gaslight Media Members Database Contacts Child Plugin
  * Uninstall Plugin
diff --git a/views/admin/member/contacts.html b/views/admin/member/contacts.html
new file mode 100644 (file)
index 0000000..bb87d19
--- /dev/null
@@ -0,0 +1,667 @@
+{include file='admin/member/header.html'}
+
+{if $userDeleted}
+    <h3><span class="glm-warning">Contact Deleted:</span></h3>
+    <ul class="glm-li">
+  {if $wpUserDeleted}
+        <li>The associated system user was also removed.</li>
+  {else}
+        <li>Other roles were assigned to the associated system user so that system user has not been removed.</li>
+  {/if}
+    </ul>
+{/if}            
+
+{if $haveMember}
+  {if $option == 'list'}
+
+    {if apply_filters('glm_members_permit_admin_member_contacts_add_contact', true)}
+    <a href="{$thisURL}?page={$thisPage}&glm_action=contacts&member={$memberID}&option=create" class="button-primary glm-button glm-right">Add New Member Contact</a>
+    {/if}
+    <form class="glm-right" onSubmit="return false;">
+       <span{if $haveFilter} class="glm-notice"{/if}><b>List Filters:</b>&nbsp;&nbsp;</span> 
+       <input type="checkbox" id="filterArchived" class="listFilter"{if $filterArchived} checked{/if}>Show Archived&nbsp;&nbsp;
+       &nbsp;&nbsp;
+       <input type="text" id="filterText" class="listFilter" value="{$filterText}"> Search
+       &nbsp;&nbsp;&nbsp;&nbsp;
+    </form>
+    <p>&nbsp;</p>
+    <table class="wp-list-table striped glm-admin-table">
+        <thead>
+            <tr>
+                <th>Name</th>
+                <th>Active</th>
+                <th>Type</th>
+                <th>Access</th>
+                <th>User</th>
+                <th>Contact For</th>
+                <th>Organization</th>
+                <th>Location</th>
+            </tr>
+        </thead>
+        <tbody>
+{if $haveContacts}
+    {foreach $contacts as $c}
+            <tr>
+                <td class="glm-shrink">
+        {if apply_filters('glm_members_permit_admin_member_contacts_view_contact', true)}
+                    <a href="{$thisURL}?page=glm-members-admin-menu-member&glm_action=contacts&option=edit&member={$c.ref_dest}&contact={$c.id}">{$c.lname}, {$c.fname}</a>
+        {else}
+                    {$c.lname}, {$c.fname}
+        {/if}                    
+                </td>
+                <td class="glm-shrink">{$c.active.name}</td>
+                <td>{$c.contact_type.name}</td>
+                <td class="glm-shrink">{$c.access.name}</td>
+                <td class="glm-nowrap">{$c.contact_role_short.name}</td>
+                <td class="glm-nowrap">{$c.ref_type.name} - {$c.ref_dest_name}</td>
+                <td class="glm-shrink">{$c.org}</td>
+                <td class="glm-shrink">{$c.city.name}, {$c.state.name}</td>
+            </tr>
+    {/foreach}
+{else}
+            <tr class="alternate"><td colspan="2">(no contacts listed)</td></tr>
+{/if}
+        </tbody>
+    </table>
+    
+<!-- Check for invalid contact ID to edit -->
+  {elseif $option == 'edit' && !$contactID}
+
+        <h3><span class="glm-error">ERROR:</span> Specified contact not found!</h3>
+        
+  {elseif $newContactExists}
+  
+        <h4><span class="glm-warning">NOTE:</span> The Email address or username for this contact is already in use. Please check if they already are a contact in this system.</h3>        
+
+  {elseif $misMatchedWpUsers}
+  
+        <h3>
+            <span class="glm-warning">NOTE:</span> 
+            The Email address for this contact is already in use by an existing system user but the username is in use by a different 
+            system user. As such we are unable to match this request to a specific existing system user. We suggest you determine what 
+            the "Username" is for the existing Wordpress user with the Email address you requested. Please call for assistance if needed.
+        </h3>        
+  
+  {elseif $newContactCreated}
+  
+        <h3><span class="glm-warning">New Contact Created:</span> {$contactInfo.fieldData.fname} {$contactInfo.fieldData.lname} - {$contactInfo.fieldData.email}</h3> 
+    {if $usernameChangedToWP || $usingExistingWPContact} 
+        <h3><span class="glm-notice">NOTE:</span></h3>
+        <ul class="glm-li">
+    {/if}
+    {if $usingExistingWPContact}
+            <li>An existing system user was found with the same Email address. This contact will be associated with that system user. </li>
+            <li>The password of the existing system user was not updated. The system user will continue to use their existing password.</li>
+    {/if}
+    {if $usernameChangedToWP}
+            <li>The username was changed to match the username of the system user found with the specified Email address.</li>
+            <li>The username for this contact is: <span class="glm-notice">{$contactInfo.fieldData.username}</span></li>
+    {/if}
+    {if $usernameChangedToWP || $usingExistingWPContact} 
+        </ul>
+    {/if}
+
+  {else} <!-- !$option -->
+
+
+   {if apply_filters('glm_members_permit_admin_member_contacts_edit_contact', true)}
+
+    {if $option == 'create' || $option == 'edit'}
+
+         <a href="{$thisURL}?page={$thisPage}&glm_action=contacts&member={$memberID}" class="button-primary glm-button glm-right">Return to Contact List</a>
+            
+      {if $option == 'create'}
+        <h2 class="glm-left">Add New Contact</h2>   
+      {else}
+        {if $contactUpdated}<h2 class="glm-notice glm-flash-updated">Contact Updated</h2>{/if}
+        <a id="deleteContactButton" class="button-primary glm-button glm-right">Delete this Contact</a>
+        <div id="deleteContactDialog" class="glm-dialog-box" title="Delete Contact">
+            <center>
+                <p><a id="deleteContactCancel" class="button-primary">Cancel</a></p>
+                <p><input id="deleteContactSubmit" type="submit" value="Delete this contact"></p>
+            </center>
+            <div class="glm-item-container">
+                <p><center><span class="glm-error">WARNING:</span></center></p>
+                <p>
+                    <span class="glm-warning">Clicking the "Delete this Contact" button above will 
+                    delete all of the data and images associated with this contact.
+                    </span>
+                </p>
+                <p>
+                    <span class="glm-error">Once deleted, this information will no longer be available and cannot be retrieved!</span>
+                </p>
+            </div>
+            <p>
+                This contact may instead be "Archived" rather than deleted using the "Contact Display:" pick-list. When archived, the contact is not displayed on the front-end
+                of the Web site, any login assoicated with this contact is deactivated, and the contact will not show on contact lists unless "Archived" is selected. 
+                Unlike delete, an archived contact may be changed back to normal use.
+            </p>
+        </div>
+        <h2 class="glm-left">Edit Contact</h2>
+      {/if}
+        
+      
+        <form action="{$thisURL}?page={$thisPage}" method="post" enctype="multipart/form-data">
+            <input type="hidden" name="glm_action" value="contacts">
+            <input type="hidden" name="member" value="{$memberData.id}">
+        {if $option == 'create'}
+            <input type="hidden" name="option" value="addNew">
+            <input type="hidden" name="create_time" value="now">
+            <input type="hidden" name="ref_type" value="{$refType}">
+            <input type="hidden" name="ref_dest" value="{$memberData.id}">
+        {else}
+            <input type="hidden" name="option" value="submit">
+            <input type="hidden" name="contact" value="{$contactInfo.fieldData.id}">
+            <input type="hidden" name="id" value="{$contactInfo.fieldData.id}">
+            <input type="hidden" name="modify_time" value="now">
+        {/if}
+                    
+            <table class="glm-admin-table glm-shrink">
+                <tr>
+                    <th>Contact For:</th>
+                    <td>{if $option=='create'}{$refTypeName}{else}{$contactInfo.fieldData.ref_type.name}{/if} - {$memberData.name}</td>
+                </tr>
+                <tr>
+                    <th>Active:</th>
+                    <td>
+                        <input type="checkbox" name="active" {if $contactInfo.fieldData.active.value} checked{/if}>
+                    </td>
+                </tr>
+            {if $option != 'create'}
+                <tr>
+                    <th>Created:</th>
+                    <td>{$contactInfo.fieldData.create_time.datetime}</td>
+                </tr>            
+                <tr>
+                    <th>Last Updated:</th>
+                    <td>{$contactInfo.fieldData.modify_time.datetime}</td>
+                </tr>
+            {/if}
+                <tr>
+                    <th {if $contactInfo.fieldRequired.fname}class="glm-required"{/if}>First Name:</th>
+                    <td {if $contactInfo.fieldFail.fname}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="fname" value="{$contactInfo.fieldData.fname}" class="glm-form-text-input-short">
+                        {if $contactInfo.fieldFail.fname}<p>{$contactInfo.fieldFail.fname}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.lname}class="glm-required"{/if}>Last Name:</th>
+                    <td {if $contactInfo.fieldFail.lname}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="lname" value="{$contactInfo.fieldData.lname}" class="glm-form-text-input-short">
+                        {if $contactInfo.fieldFail.lname}<p>{$contactInfo.fieldFail.lname}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.contact_type}class="glm-required"{/if}>Contact Type:</th>
+                    <td {if $contactInfo.fieldFail.contact_type}class="glm-form-bad-input"{/if}>
+                        <select name="contact_type">
+            {foreach from=$contactInfo.fieldData.contact_type.list item=v}
+                            <option value="{$v.value}"{if $v.default} selected="selected"{/if}>
+                                {$v.name}
+                            </option>
+            {/foreach}
+                        </select>
+                        {if $contactInfo.fieldFail.contact_type}<p>{$contactInfo.fieldFail.contact_type}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.contact_role}class="glm-required"{/if}>Permissions:</th>
+                    <td {if $contactInfo.fieldFail.contact_role}class="glm-form-bad-input"{/if}>
+                        <select name="contact_role">
+            {foreach from=$contactInfo.fieldData.contact_role.list item=v}
+                            <option value="{$v.value}"{if $v.default} selected="selected"{/if}>
+                                {$v.name}
+                            </option>
+            {/foreach}
+                        </select>
+                        {if $contactInfo.fieldFail.contact_role}<p>{$contactInfo.fieldFail.contact_role}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.access}class="glm-required"{/if}>Display/Moderate/Archive:</th>
+                    <td {if $contactInfo.fieldFail.access}class="glm-form-bad-input"{/if}>
+                        <select name="access">
+            {foreach from=$contactInfo.fieldData.access.list item=v}
+                            <option value="{$v.value}"{if $v.default} selected="selected"{/if}>{$v.name}</option>
+            {/foreach}
+                        </select>
+                        {if $contactInfo.fieldFail.access}<p>{$contactInfo.fieldFail.access}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+            {if $option == 'create'}                
+                    <th {if $contactInfo.fieldRequired.email}class="glm-required"{/if}>Email Address:</th>
+                    <td {if $contactInfo.fieldFail.email}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="email" value="{$contactInfo.fieldData.email}" class="glm-form-text-input-medium" placeholder="(ex: name@domain.com)">
+                        <br><span class="glm-notice">NOTE:</span> This field is required for users who will have login privileges.
+                        {if $contactInfo.fieldFail.email}<p>{$contactInfo.fieldFail.email}</p>{/if}
+                    </td>
+            {else}
+                    <th>Email Address::</th>
+                    <td>{$contactInfo.fieldData.email}</td>
+            {/if}
+                </tr>
+                <tr>
+                
+            {if $option == 'create'}                
+                    <th {if $contactInfo.fieldRequired.username}class="glm-required"{/if}>Login Username:</th>
+                    <td {if $contactInfo.fieldFail.username}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="username" value="{$contactInfo.fieldData.username}" class="glm-form-text-input-medium" placeholder="(no spaces permitted)">
+                        <br><span class="glm-notice">NOTE:</span> The username cannot be changed once the contact is created.
+                        {if $contactInfo.fieldFail.username}<p>{$contactInfo.fieldFail.username}</p>{/if}
+                    </td>
+            {else}
+                    <th>Login Username:</th>
+                    <td>{$contactInfo.fieldData.username}</td>
+            {/if}
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.password}class="glm-required"{/if}>Login password:</th>
+                    <td {if $contactInfo.fieldFail.password}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="password" value="{$contactInfo.fieldData.password}" class="glm-form-text-input-medium" placeholder="{if $option=='create'}(no spaces permitted){else}(Password does not show, only enter to change password.){/if}">
+                        {if $option == 'create'}
+                            <span class="glm-notice">Save this password.</span> 
+                            <br>A randomly generated password has been supplied. You may change this as desired.
+                            There is no way to view a password once it's set. However, a user may recover a password using their
+                            Email address at the login page.
+                        {/if}
+                        {if $contactInfo.fieldFail.password}<p>{$contactInfo.fieldFail.password}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.alt_email}class="glm-required"{/if}>Alternate Email Address:</th>
+                    <td {if $contactInfo.fieldFail.alt_email}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="alt_email" value="{$contactInfo.fieldData.alt_email}" class="glm-form-text-input-short" placeholder="ex: name@domain.com">
+                        {if $contactInfo.fieldFail.alt_email}<p>{$contactInfo.fieldFail.alt_email}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.org}class="glm-required"{/if}>Organization:</th>
+                    <td {if $contactInfo.fieldFail.org}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="org" value="{$contactInfo.fieldData.org}" class="glm-form-text-input-medium">
+                        {if $contactInfo.fieldFail.org}<p>{$contactInfo.fieldFail.org}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.title}class="glm-required"{/if}>Title/Position:</th>
+                    <td {if $contactInfo.fieldFail.title}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="title" value="{$contactInfo.fieldData.title}" class="glm-form-text-input-medium">
+                        {if $contactInfo.fieldFail.title}<p>{$contactInfo.fieldFail.title}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.descr}class="glm-required"{/if}>Position/Responsibilities:</th>
+                    <td {if $contactInfo.fieldFail.descr}class="glm-form-bad-input"{/if}>
+                        {php}
+                            wp_editor('{$contactInfo.fieldData.descr}', 'glm_descr', array(
+                                'quicktags' => false,
+                                'media_buttons' => false,
+                                'wpautop' => false,
+                                'textarea_name' => 'descr',
+                                'editor_height' => 100,     // Height in px, overrides editor_rows
+                                    // 'textarea_rows' => 4,
+                            ));
+                        {/php}
+                        {if $contactInfo.fieldFail.descr}<p>{$contactInfo.fieldFail.descr}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.image}class="glm-required"{/if}>Image:</th>
+                    <td {if $contactInfo.fieldFail.image}class="glm-form-bad-input"{/if}>
+            {if $contactInfo.fieldData.image}
+                        <div id="largeImageDialog" class="glm-dialog-box" title="Large sized image">
+                            <img src="{$glmPluginMediaURL}/images/large/{$contactInfo.fieldData.image}">
+                            <a id="largeImageCancel" class="button-primary glm-right">Close</a><br>
+                        </div>
+                        <table class="glm-admin-image-edit-table">
+                            <tr>
+                                <td><img src="{$glmPluginMediaURL}/images/thumb/{$contactInfo.fieldData.image}"></td> 
+                                <td>
+                                    <input type="checkbox" name="image_delete"> Delete Image<br>
+                                    {$contactInfo.fieldData.image}<br>
+                                    <p><div id="largeImageButton" class="button-primary">Show Large Image</div></p>
+                                </td>
+                        
+                            </tr>
+                        </table>
+            {/if}
+                        <input type="file" name="image_new">
+                        {if $contactInfo.fieldFail.image}<p>{$contactInfo.fieldFail.image}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.addr1}class="glm-required"{/if}>Address Line 1:</th>
+                    <td {if $contactInfo.fieldFail.addr1}class="glm-form-bad-input"{/if}>
+                        <input type="text" id="addr1" name="addr1" value="{$contactInfo.fieldData.addr1}" class="glm-form-text-input glm-geocodeAction">
+                        {if $contactInfo.fieldFail.addr1}<p>{$contactInfo.fieldFail.addr1}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.addr2}class="glm-required"{/if}>Address Line 2:</th>
+                    <td {if $contactInfo.fieldFail.addr2}class="glm-form-bad-input"{/if}>
+                        <input id="addr2" type="text" name="addr2" value="{$contactInfo.fieldData.addr2}" class="glm-form-text-input glm-geocodeAction">
+                        {if $contactInfo.fieldFail.addr2}<p>{$contactInfo.fieldFail.addr2}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th>City</th>
+                    <td class="glm-item-container">
+                        <!--  Add new city dialog -->
+                        <div id="newCityButton" class="button-primary glm-right">Add a new City</div>
+                        <div id="newCityDialog" class="glm-dialog-box" title="Enter a New City">
+                            <table class="glm-admin-table">
+                                <tr>
+                                    <th class="glm-required">City Name:</th>
+                                    <td id="newCityNameTD">
+                                        <input id="newCityName" type="text" name="newCityName" class="glm-form-text-input">
+                                        <div id="newCityNameRequired"></div>
+                                    </td>
+                                </tr>
+                            </table>
+                            <p><span class="glm-required">*</span> Required</p>
+                            <a id="newCityCancel" class="button-primary glm-right">Cancel</a>
+                            <input id="newCitySubmit" type="submit" value="Add new City">
+                        </div>
+                        <!-- City Selection -->
+                        <input id="cityName" type="hidden" name="newCityName" value=""><!-- this field is only used if adding a new city to pass the new name -->
+                        <select name="city" id="city" class="glm-geocodeAction">
+                            <option value="0"><option>
+            {foreach from=$contactInfo.fieldData.city.list item=v}
+                            <option value="{$v.value}"{if $v.default} selected="selected"{/if}>
+                                {$v.name}
+                            </option>
+            {/foreach}
+                        </select>
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.state}class="glm-required"{/if}>State:</th>
+                    <td {if $contactInfo.fieldFail.state}class="glm-form-bad-input"{/if}>
+                        <select id="state" name="state" class="glm-geocodeAction">
+            {foreach from=$contactInfo.fieldData.state.list item=v}
+                            <option value="{$v.value}"{if $v.default} selected="selected"{/if}>
+                                {$v.name}
+                            </option>
+            {/foreach}
+                        </select>
+                        {if $contactInfo.fieldFail.state}<p>{$contactInfo.fieldFail.state}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.zip}class="glm-required"{/if}>ZIP / Postal Code:</th>
+                    <td {if $contactInfo.fieldFail.zip}class="glm-form-bad-input"{/if}>
+                        <input id="zip" type="text" name="zip" value="{$contactInfo.fieldData.zip}" class="glm-form-text-input-short glm-geocodeAction">
+                        {if $contactInfo.fieldFail.zip}<p>{$contactInfo.fieldFail.zip}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.country}class="glm-required"{/if}>Country:</th>
+                    <td {if $contactInfo.fieldFail.country}class="glm-form-bad-input"{/if}>
+                        <select id="country" name="country" class="glm-geocodeAction">
+            {foreach from=$contactInfo.fieldData.country.list item=v}
+                            <option value="{$v.value}"{if $v.default} selected="selected"{/if}>
+                                {$v.name} {$v.value}
+                            </option>
+            {/foreach}
+                        </select>
+                        {if $contactInfo.fieldFail.country}<p>{$contactInfo.fieldFail.country}</p>{/if}
+                    </td>
+                </tr>
+            <!-- NOT DOING LAT/LON FOR NOW -->
+                <tr>
+                    <th {if $contactInfo.fieldRequired.url}class="glm-required"{/if}>Web Address (URL):</th>
+                    <td {if $contactInfo.fieldFail.url}class="glm-form-bad-input"{/if}>
+            {if $contactInfo.fieldData.url}
+                        <a class="button-primary glm-right" href="http://{$contactInfo.fieldData.url}" target="urlTarget">Test Link</a>
+            {/if}
+                        http://<input type="text" name="url" value="{$contactInfo.fieldData.url}" class="glm-form-text-input-medium" placeholder="ex: www.gaslightmedia.com">
+                        {if $contactInfo.fieldFail.url}<p>{$contactInfo.fieldFail.url}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.office_phone}class="glm-required"{/if}>Office Phone #:</th>
+                    <td {if $contactInfo.fieldFail.office_phone}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="office_phone" value="{$contactInfo.fieldData.office_phone}" class="glm-form-text-input-short" placeholder="ex: 123-456-7890 ext 123">
+                        {if $contactInfo.fieldFail.office_phone}<p>{$contactInfo.fieldFail.office_phone}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.home_phone}class="glm-required"{/if}>Home Phone #:</th>
+                    <td {if $contactInfo.fieldFail.home_phone}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="home_phone" value="{$contactInfo.fieldData.home_phone}" class="glm-form-text-input-short" placeholder="ex: 123-456-7890 ext 123">
+                        {if $contactInfo.fieldFail.home_phone}<p>{$contactInfo.fieldFail.home_phone}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.mobile_phone}class="glm-required"{/if}>Mobile Phone #:</th>
+                    <td {if $contactInfo.fieldFail.mobile_phone}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="mobile_phone" value="{$contactInfo.fieldData.mobile_phone}" class="glm-form-text-input-short" placeholder="ex: 123-456-7890 ext 123">
+                        {if $contactInfo.fieldFail.mobile_phone}<p>{$contactInfo.fieldFail.mobile_phone}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.alt_phone}class="glm-required"{/if}>Alternate Phone #:</th>
+                    <td {if $contactInfo.fieldFail.alt_phone}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="alt_phone" value="{$contactInfo.fieldData.alt_phone}" class="glm-form-text-input-short" placeholder="ex: 123-456-7890 ext 123">
+                        {if $contactInfo.fieldFail.alt_phone}<p>{$contactInfo.fieldFail.alt_phone}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.fax}class="glm-required"{/if}>FAX #:</th>
+                    <td {if $contactInfo.fieldFail.fax}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="fax" value="{$contactInfo.fieldData.fax}" class="glm-form-text-input-short" placeholder="ex: 123-456-7890 ext 123">
+                        {if $contactInfo.fieldFail.fax}<p>{$contactInfo.fieldFail.fax}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.notes}class="glm-required"{/if}>Notes:</th>
+                    <td {if $contactInfo.fieldFail.notes}class="glm-form-bad-input"{/if}>
+                        {php}
+                            wp_editor('{$contactInfo.fieldData.notes}', 'glm_notes', array(
+                                'quicktags' => false,
+                                'media_buttons' => false,
+                                'wpautop' => false,
+                                'textarea_name' => 'notes',
+                                'editor_height' => 100,     // Height in px, overrides editor_rows
+                                    // 'textarea_rows' => 4,
+                            ));
+                        {/php}
+                        {if $contactInfo.fieldFail.notes}<p>{$contactInfo.fieldFail.notes}</p>{/if}
+                    </td>
+                </tr>
+            </table>
+            <p><span class="glm-required">*</span> Required</p>
+            <input type="submit" name="Add new member">
+        </form>  
+        
+    {/if}
+
+   {else} <!-- may edit contact -->
+
+            <table class="glm-admin-table glm-shrink">
+                <tr><th>Contact For:</th><td>{$contactInfo.fieldData.ref_type.name} - {$memberData.name}</td></tr>
+                <tr><th>Active:</th><td>{$contactInfo.fieldData.active.name}</td></tr>
+                <tr><th>Created:</th><td>{$contactInfo.fieldData.create_time.datetime}</td></tr>            
+                <tr><th>Last Updated:</th><td>{$contactInfo.fieldData.modify_time.datetime}</td></tr>
+                <tr><th>First Name:</th><td>{$contactInfo.fieldData.fname}</td></tr>
+                <tr><th>Last Name:</th><td>{$contactInfo.fieldData.lname}</td></tr>
+                <tr><th>Contact Type:</th><td>{$contactInfo.fieldData.contact_type.name}</td></tr>
+                <tr><th>Email Address::</th><td>{$contactInfo.fieldData.email}</td></tr>
+                <tr><th>Alternate Email Address:</th><td>{$contactInfo.fieldData.alt_email}</td></tr>
+                <tr><th>Organization:</th><td>{$contactInfo.fieldData.org}</td></tr>
+                <tr><th>Title/Position:</th><td>{$contactInfo.fieldData.title}</td></tr>
+                <tr><th>Position/Responsibilities:</th><td>{$contactInfo.fieldData.descr}</td></tr>
+                <tr>
+                    <th>Image:</th>
+                    <td>
+            {if $contactInfo.fieldData.image}
+                        <img src="{$glmPluginMediaURL}/images/thumb/{$contactInfo.fieldData.image}">
+            {/if} 
+                    </td>
+                </tr>
+                <tr><th>Address Line 1:</th><td>{$contactInfo.fieldData.addr1}</td></tr>
+                <tr><th>Address Line 2:</th><td>{$contactInfo.fieldData.addr2}</td></tr>
+                <tr><th>City</th><td>{$contactInfo.fieldData.city.name}</td></tr>
+                <tr><th>State:</th><td>{$contactInfo.fieldData.state.name}</td></tr>
+                <tr><th>ZIP / Postal Code:</th><td>{$contactInfo.fieldData.zip}</td></tr>
+                <tr><th>Country:</th><td>{$contactInfo.fieldData.country.name}</td></tr>
+                <tr>
+                    <th>Web Address (URL):</th>
+                    <td>
+            {if $contactInfo.fieldData.url}
+                        <a href="http://{$contactInfo.fieldData.url}" target="urlTarget">{$contactInfo.fieldData.url}</a>
+            {/if}
+                    </td>
+                </tr>
+                <tr><th>Office Phone #:</th><td>{$contactInfo.fieldData.office_phone}</td></tr>
+                <tr><th>Home Phone #:</th><td>{$contactInfo.fieldData.home_phone}</td></tr>
+                <tr><th>Mobile Phone #:</th><td>{$contactInfo.fieldData.mobile_phone}</td></tr>
+                <tr><th>Alternate Phone #:</th><td>{$contactInfo.fieldData.alt_phone}</td></tr>
+                <tr><th>FAX #:</th><td>{$contactInfo.fieldData.fax}</td></tr>
+                <tr><th>Notes:</th><td>{$contactInfo.fieldData.notes}</td></tr>
+            </table>
+   {/if} <!-- mey edit contact -->
+
+  {/if} <!-- /if option -->
+
+{else} <!-- Member not specified or not found -->
+    <h2><span class="glm-error">ERROR:</span> Specified member not found!</h2>
+{/if}
+
+    <script type="text/javascript">
+        jQuery(document).ready(function($) {
+            
+            // Filter triggers
+            $(".listFilter" ).change( function() {
+                
+                var filter = '';
+                
+                // Check for archived filter
+                if ($("#filterArchived").attr('checked')) {
+                    filter += '&filterArchived=true';
+                }
+                
+                // Check for name filter
+                var filterText = $("#filterText").val();
+                if (filterText != '') {
+                    filter += '&filterText=' + encodeURIComponent(filterText).replace(/%20/g,'+');
+                }
+                
+                window.location.href = "{$thisURL}?page={$thisPage}&glm_action=contacts&member={$memberID}" + filter;
+                
+                return false;
+            });
+
+            /*
+             * New City Dialog
+             */
+
+            // Setup dialog box for adding a new city
+            $("#newCityDialog").dialog({
+                autoOpen: false,
+                minWidth: 400,
+                dialogClass: "glm-dialog-no-close"
+            });
+            $('#newCityCancel').click( function() {
+                $("#newCityDialog").dialog("close");
+            });
+             
+            // Ad a new city button action - pop-up dialog
+            $('#newCityButton').click( function() {
+                $("#newCityDialog").dialog("open");
+            });
+
+            // Submit new city
+            var newCityAdded = false;
+            $('#newCitySubmit').click( function() {
+                
+                // Get new city name
+                var newCityName = $('#newCityName').val();
+
+                // If no name is supplied, notify used it's required
+                if (newCityName == '') {
+                    $('#newCityNameTD').addClass('glm-form-bad-input');
+                    $('#newCityNameRequired').text('A city name is required!');
+                    return false;
+                }
+
+                // Add new city name to the hidden field that will pass the new name to PHP.
+                $('#cityName').val(newCityName);
+                
+                // Add new city name to picklist and for storing - Only one permitted per submission
+                if (newCityAdded) {
+                    
+                    // New city already added, so just update the name and select that one
+                    $('#city').val(-1);
+                    $('#city option:selected').text(newCityName);
+                    
+                } else {
+                    
+                    // Add the new city name to the city picklist
+                    $('#city').append('<option value="-1">' + newCityName + '</option>');
+                    $('#city').val(-1);
+                    $('#newCityNameTD').append('<input type="hidden" name="newCity" value="' + newCityName + '">');
+                    newCityAdded = true;
+
+                }
+      
+                // Clear new city name from form
+                $('#newCityName').val('');
+                
+                $("#newCityDialog").dialog("close");
+
+            });
+
+            /*
+             * Large Image Dialog
+             */
+
+            // Setup dialog box for showing enlarged image image
+            x = $('#largeImageDialog').dialog({
+                autoOpen: false,
+                resizable: false,
+                dialogClass: "glm-dialog-no-close"
+            });
+            $('#largeImageCancel').click( function() {
+                $('#largeImageDialog').dialog("close");
+            });
+
+            // Show large image - pop-up dialog - resize at time of pop-up
+            $('#largeImageButton').click( function() {
+                $("#largeImageDialog").dialog("open");
+                $( "#largesImageDialog" ).dialog( "option", "position", { my: "center", at: "center", of: window } );
+                var newWidth = $(window).width() * .8;
+                $( "#largeImageDialog" ).dialog( "option", "width", newWidth );
+            });
+
+            // Resize whenever window size changes
+            $(window).resize(function(){
+                $( "#largeImageDialog" ).dialog( "option", "position", { my: "center", at: "center", of: window } );
+                var newWidth = $(window).width() * .8;
+                $( "#largeImageDialog" ).dialog( "option", "width", newWidth );
+            });
+
+            // Delete Contact dialog
+            $("#deleteContactDialog").dialog({
+                autoOpen: false,
+                minWidth: 400,
+                dialogClass: "glm-dialog-no-close"
+            });
+            $('#deleteContactButton').click( function() {
+                $('#deleteContactDialog').dialog('open');
+            });
+            $('#deleteContactCancel').click( function() {
+                $("#deleteContactDialog").dialog("close");
+            });            
+            $('#deleteContactSubmit').click( function() {
+                window.location.replace("{$thisURL}?page={$thisPage}&glm_action=contacts&member={$memberID}&option=delete&contact={$contactID}");
+            });
+
+            // 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>
+
+
+{include file='admin/footer.html'}
diff --git a/views/admin/members/contacts.html b/views/admin/members/contacts.html
new file mode 100644 (file)
index 0000000..ae8d06c
--- /dev/null
@@ -0,0 +1,75 @@
+{include file='admin/members/header.html'}
+
+    <form class="glm-right" onSubmit="return false;">
+       <span{if $haveFilter} class="glm-notice"{/if}><b>List Filters:</b>&nbsp;&nbsp;</span> 
+       <input type="checkbox" id="filterArchived" class="listFilter"{if $filterArchived} checked{/if}>Show Archived&nbsp;&nbsp;
+       &nbsp;&nbsp;
+       <input type="text" id="filterText" class="listFilter" value="{$filterText}"> Search
+    </form>
+    <h2 class="glm-left">Contacts</h2>
+
+    <table class="wp-list-table striped glm-admin-table">
+        <thead>
+            <tr>
+                <th>Name</th>
+                <th>Active</th>
+                <th>Type</th>
+                <th>Access</th>
+                <th>User</th>
+                <th>Entity</th>
+                <th>Organization</th>
+                <th>Location</th>
+            </tr>
+        </thead>
+        <tbody>
+{if $haveContacts}
+    {foreach $contacts as $c}
+            <tr>
+                <td class="glm-shrink"><a href="{$thisURL}?page=glm-members-admin-menu-member&glm_action=contacts&option=edit&member={$c.ref_dest}&contact={$c.id}">{$c.lname}, {$c.fname}</a></td>
+                <td class="glm-shrink">{$c.active.name}</td>
+                <td>{$c.contact_type.name}</td>
+                <td class="glm-shrink">{$c.access.name}</td>
+                <td class="glm-nowrap">{$c.contact_role_short.name}</td>
+                <td class="glm-nowrap">
+                    {$c.ref_type.name}: 
+                    <a href="{$thisURL}?page=glm-members-admin-menu-member&glm_action=index&member={$c.ref_dest}">{$c.ref_dest_name}</a>
+                </td>
+                <td class="glm-shrink">{$c.org}</td>
+                <td class="glm-shrink">{$c.city.name}, {$c.state.name}</td>
+            </tr>
+    {/foreach}
+{else}
+            <tr class="alternate"><td colspan="2">(no contacts listed)</td></tr>
+{/if}
+        </tbody>
+    </table>
+
+    <script type="text/javascript">
+        jQuery(document).ready(function($) {
+            
+            // Filter triggers
+            $(".listFilter" ).change( function() {
+                
+                var filter = '';
+                
+                // Check for archived filter
+                if ($("#filterArchived").attr('checked')) {
+                    filter += '&filterArchived=true';
+                }
+                
+                // Check for text filter
+                var filterText = $("#filterText").val();
+                if (filterText != '') {
+                    filter += '&filterText=' + encodeURIComponent(filterText).replace(/%20/g,'+');
+                }
+                
+                window.location.href = "{$thisURL}?page={$thisPage}&glm_action=contacts" + filter;
+                
+                return false;
+            });
+        });
+    </script>
+            
+
+
+{include file='admin/footer.html'}
diff --git a/views/admin/profile/index.html b/views/admin/profile/index.html
new file mode 100644 (file)
index 0000000..4d25992
--- /dev/null
@@ -0,0 +1,407 @@
+<div class="wrap">
+
+    <h2>Your Contact and Log-in Profile</h2>
+  
+    <h2 class="nav-tab-wrapper">
+        <a href="{$thisURL}?page={$thisPage}&glm_action=index" class="nav-tab{if $thisAction==index}-active{/if}">Profile</a>
+    </h2>
+    <div id="glm-admin-content-container">
+   
+{if apply_filters('glm_members_permit_admin_profile_index_edit_profile', true)}
+
+        <p>
+        <b>Why are there items below that I can't edit?</b><br>
+        Some of the information below, such as your Username and Email address, are used by the system to identify your profile and may not be altered after the contact profile has been created. 
+        There are also certain items that relate to permissions you have to access and change other data.
+        </p>
+        
+        {if $contactUpdated}<h2 class="glm-notice glm-flash-updated">Contact Updated</h2>{/if}
+        <form action="{$thisURL}?page={$thisPage}" method="post" enctype="multipart/form-data">
+            <input type="hidden" name="glm_action" value="index">
+            <input type="hidden" name="option" value="submit">
+            <input type="hidden" name="contact" value="{$contactInfo.fieldData.id}">
+            <input type="hidden" name="id" value="{$contactInfo.fieldData.id}">
+            <input type="hidden" name="modify_time" value="now">
+                    
+            <table class="glm-admin-table glm-shrink">
+                <tr>
+                    <th>Contact For:</th>
+                    <td>{$contactInfo.fieldData.ref_type.name} - {$contactInfo.fieldData.ref_dest_name}</td>
+                </tr>
+                <tr><th>Active:</th><td>{$contactInfo.fieldData.active.name}</td></tr>
+                <tr>
+                    <th>Created:</th>
+                    <td>{$contactInfo.fieldData.create_time.datetime}</td>
+                </tr>            
+                <tr>
+                    <th>Last Updated:</th>
+                    <td>{$contactInfo.fieldData.modify_time.datetime}</td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.fname}class="glm-required"{/if}>First Name:</th>
+                    <td {if $contactInfo.fieldFail.fname}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="fname" value="{$contactInfo.fieldData.fname}" class="glm-form-text-input-short">
+                        {if $contactInfo.fieldFail.fname}<p>{$contactInfo.fieldFail.fname}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.lname}class="glm-required"{/if}>Last Name:</th>
+                    <td {if $contactInfo.fieldFail.lname}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="lname" value="{$contactInfo.fieldData.lname}" class="glm-form-text-input-short">
+                        {if $contactInfo.fieldFail.lname}<p>{$contactInfo.fieldFail.lname}</p>{/if}
+                    </td>
+                </tr>
+                <tr><th>Contact Type:</th><td>{$contactInfo.fieldData.contact_type.name}</td></tr>
+                <tr><th>Permissions:</th><td>{$contactInfo.fieldData.contact_role.name}</td></tr>
+                <tr><th class="glm-nowrap">Display/Moderate/Archive:</th><td>{$contactInfo.fieldData.access.name}</td></tr>
+                <tr><th>Email Address::</th><td>{$contactInfo.fieldData.email}</td></tr>
+                <tr><th>Login Username:</th><td>{$contactInfo.fieldData.username}</td></tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.password}class="glm-required"{/if}>Login password:</th>
+                    <td {if $contactInfo.fieldFail.password}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="password" value="{$contactInfo.fieldData.password}" class="glm-form-text-input-medium" placeholder="(password not displayed)">
+                        <br>Your existing password is not displayed. If you would like to change your password, enter it above. 
+                        {if $contactInfo.fieldFail.password}<p>{$contactInfo.fieldFail.password}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.alt_email}class="glm-required"{/if}>Alternate Email Address:</th>
+                    <td {if $contactInfo.fieldFail.alt_email}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="alt_email" value="{$contactInfo.fieldData.alt_email}" class="glm-form-text-input-short" placeholder="(ex: name@domain.com)">
+                        {if $contactInfo.fieldFail.alt_email}<p>{$contactInfo.fieldFail.alt_email}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.org}class="glm-required"{/if}>Organization:</th>
+                    <td {if $contactInfo.fieldFail.org}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="org" value="{$contactInfo.fieldData.org}" class="glm-form-text-input-medium">
+                        {if $contactInfo.fieldFail.org}<p>{$contactInfo.fieldFail.org}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.title}class="glm-required"{/if}>Title/Position:</th>
+                    <td {if $contactInfo.fieldFail.title}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="title" value="{$contactInfo.fieldData.title}" class="glm-form-text-input-medium">
+                        {if $contactInfo.fieldFail.title}<p>{$contactInfo.fieldFail.title}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.descr}class="glm-required"{/if}>Position/Responsibilities:</th>
+                    <td {if $contactInfo.fieldFail.descr}class="glm-form-bad-input"{/if}>
+                        {php}
+                            wp_editor('{$contactInfo.fieldData.descr}', 'glm_descr', array(
+                                'quicktags' => false,
+                                'media_buttons' => false,
+                                'wpautop' => false,
+                                'textarea_name' => 'descr',
+                                'editor_height' => 100,     // Height in px, overrides editor_rows
+                                    // 'textarea_rows' => 4,
+                            ));
+                        {/php}
+                        {if $contactInfo.fieldFail.descr}<p>{$contactInfo.fieldFail.descr}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.image}class="glm-required"{/if}>image:</th>
+                    <td {if $contactInfo.fieldFail.image}class="glm-form-bad-input"{/if}>
+                        <table class="glm-admin-image-edit-table">
+            {if $contactInfo.fieldData.image}
+                            <tr>
+                                <td>
+                                    <div class="glm-galleryImage" data-id="image">
+                                        <img src="{$glmPluginMediaURL}/images/small/{$contactInfo.fieldData.image}">
+                                    </div>
+                                </td>
+                                <td>
+                                    <input type="checkbox" name="image_delete"> Delete Image<br>
+                                    {$contactInfo.fieldData.image}<br>
+                                </td>
+                            </tr>
+            {/if}
+                            <tr><td colspan="2"><b>New image:</b> <input type="file" name="image_new"></td></tr>
+                        </table>
+                        <div id="glm-galleryImageLarger_image" class="glm-imageDialog"><img src="{$glmPluginMediaURL}/images/large/{$contactInfo.fieldData.image}"></div>
+                        {if $contactInfo.fieldFail.image}<p>{$contactInfo.fieldFail.image}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.addr1}class="glm-required"{/if}>Address Line 1:</th>
+                    <td {if $contactInfo.fieldFail.addr1}class="glm-form-bad-input"{/if}>
+                        <input type="text" id="addr1" name="addr1" value="{$contactInfo.fieldData.addr1}" class="glm-form-text-input glm-geocodeAction">
+                        {if $contactInfo.fieldFail.addr1}<p>{$contactInfo.fieldFail.addr1}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.addr2}class="glm-required"{/if}>Address Line 2:</th>
+                    <td {if $contactInfo.fieldFail.addr2}class="glm-form-bad-input"{/if}>
+                        <input id="addr2" type="text" name="addr2" value="{$contactInfo.fieldData.addr2}" class="glm-form-text-input glm-geocodeAction">
+                        {if $contactInfo.fieldFail.addr2}<p>{$contactInfo.fieldFail.addr2}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th>City</th>
+                    <td class="glm-item-container">
+                        <!--  Add new city dialog -->
+                        <div id="newCityButton" class="button-primary glm-right">Add a new City</div>
+                        <div id="newCityDialog" class="glm-dialog-box" title="Enter a New City">
+                            <table class="glm-admin-table">
+                                <tr>
+                                    <th class="glm-required">City Name:</th>
+                                    <td id="newCityNameTD">
+                                        <input id="newCityName" type="text" name="newCityName" class="glm-form-text-input">
+                                        <div id="newCityNameRequired"></div>
+                                    </td>
+                                </tr>
+                            </table>
+                            <p><span class="glm-required">*</span> Required</p>
+                            <a id="newCityCancel" class="button-primary glm-right">Cancel</a>
+                            <input id="newCitySubmit" type="submit" value="Add new City">
+                        </div>
+                        <!-- City Selection -->
+                        <input id="cityName" type="hidden" name="newCityName" value=""><!-- this field is only used if adding a new city to pass the new name -->
+                        <select name="city" id="city" class="glm-geocodeAction">
+                            <option value="0"><option>
+            {foreach from=$contactInfo.fieldData.city.list item=v}
+                            <option value="{$v.value}"{if $v.default} selected="selected"{/if}>
+                                {$v.name}
+                            </option>
+            {/foreach}
+                        </select>
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.state}class="glm-required"{/if}>State:</th>
+                    <td {if $contactInfo.fieldFail.state}class="glm-form-bad-input"{/if}>
+                        <select id="state" name="state" class="glm-geocodeAction">
+            {foreach from=$contactInfo.fieldData.state.list item=v}
+                            <option value="{$v.value}"{if $v.default} selected="selected"{/if}>
+                                {$v.name}
+                            </option>
+            {/foreach}
+                        </select>
+                        {if $contactInfo.fieldFail.state}<p>{$contactInfo.fieldFail.state}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.zip}class="glm-required"{/if}>ZIP / Postal Code:</th>
+                    <td {if $contactInfo.fieldFail.zip}class="glm-form-bad-input"{/if}>
+                        <input id="zip" type="text" name="zip" value="{$contactInfo.fieldData.zip}" class="glm-form-text-input-short glm-geocodeAction">
+                        {if $contactInfo.fieldFail.zip}<p>{$contactInfo.fieldFail.zip}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.country}class="glm-required"{/if}>Country:</th>
+                    <td {if $contactInfo.fieldFail.country}class="glm-form-bad-input"{/if}>
+                        <select id="country" name="country" class="glm-geocodeAction">
+            {foreach from=$contactInfo.fieldData.country.list item=v}
+                            <option value="{$v.value}"{if $v.default} selected="selected"{/if}>
+                                {$v.name} {$v.value}
+                            </option>
+            {/foreach}
+                        </select>
+                        {if $contactInfo.fieldFail.country}<p>{$contactInfo.fieldFail.country}</p>{/if}
+                    </td>
+                </tr>
+            <!-- NOT DOING LAT/LON FOR NOW -->
+                <tr>
+                    <th {if $contactInfo.fieldRequired.url}class="glm-required"{/if}>Web Address (URL):</th>
+                    <td {if $contactInfo.fieldFail.url}class="glm-form-bad-input"{/if}>
+            {if $contactInfo.fieldData.url}
+                        <a class="button-primary glm-right" href="http://{$contactInfo.fieldData.url}" target="urlTarget">Test Link</a>
+            {/if}
+                        http://<input type="text" name="url" value="{$contactInfo.fieldData.url}" class="glm-form-text-input-medium" placeholder="ex: www.gaslightmedia.com">
+                        {if $contactInfo.fieldFail.url}<p>{$contactInfo.fieldFail.url}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.office_phone}class="glm-required"{/if}>Office Phone #:</th>
+                    <td {if $contactInfo.fieldFail.office_phone}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="office_phone" value="{$contactInfo.fieldData.office_phone}" class="glm-form-text-input-short" placeholder="ex: 123-456-7890 ext 123">
+                        {if $contactInfo.fieldFail.office_phone}<p>{$contactInfo.fieldFail.office_phone}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.home_phone}class="glm-required"{/if}>Home Phone #:</th>
+                    <td {if $contactInfo.fieldFail.home_phone}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="home_phone" value="{$contactInfo.fieldData.home_phone}" class="glm-form-text-input-short" placeholder="ex: 123-456-7890 ext 123">
+                        {if $contactInfo.fieldFail.home_phone}<p>{$contactInfo.fieldFail.home_phone}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.mobile_phone}class="glm-required"{/if}>Mobile Phone #:</th>
+                    <td {if $contactInfo.fieldFail.mobile_phone}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="mobile_phone" value="{$contactInfo.fieldData.mobile_phone}" class="glm-form-text-input-short" placeholder="ex: 123-456-7890 ext 123">
+                        {if $contactInfo.fieldFail.mobile_phone}<p>{$contactInfo.fieldFail.mobile_phone}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.alt_phone}class="glm-required"{/if}>Alternate Phone #:</th>
+                    <td {if $contactInfo.fieldFail.alt_phone}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="alt_phone" value="{$contactInfo.fieldData.alt_phone}" class="glm-form-text-input-short" placeholder="ex: 123-456-7890 ext 123">
+                        {if $contactInfo.fieldFail.alt_phone}<p>{$contactInfo.fieldFail.alt_phone}</p>{/if}
+                    </td>
+                </tr>
+                <tr>
+                    <th {if $contactInfo.fieldRequired.fax}class="glm-required"{/if}>FAX #:</th>
+                    <td {if $contactInfo.fieldFail.fax}class="glm-form-bad-input"{/if}>
+                        <input type="text" name="fax" value="{$contactInfo.fieldData.fax}" class="glm-form-text-input-short" placeholder="ex: 123-456-7890 ext 123">
+                        {if $contactInfo.fieldFail.fax}<p>{$contactInfo.fieldFail.fax}</p>{/if}
+                    </td>
+                </tr>
+            </table>
+            <p><span class="glm-required">*</span> Required</p>
+            <input type="submit" name="Add new member">
+        </form>  
+
+    {else} <!-- may edit contact -->
+    
+        <h3>You do not have permission to edit your profile.</h3>
+        <table class="glm-admin-table striped glm-shrink">
+            <tr><th>Contact For:</th><td>{$contactInfo.fieldData.ref_type.name} - {$contactInfo.fieldData.ref_dest_name}</td></tr>
+            <tr><th>Active:</th><td>{$contactInfo.fieldData.active.name}</td></tr>
+            <tr><th>Created:</th><td>{$contactInfo.fieldData.create_time.datetime}</td></tr>            
+            <tr><th>Last Updated:</th><td>{$contactInfo.fieldData.modify_time.datetime}</td></tr>
+            <tr><th>First Name:</th><td>{$contactInfo.fieldData.fname}</td></tr>
+            <tr><th>Last Name:</th><td>{$contactInfo.fieldData.lname}</td></tr>
+            <tr><th>Contact Type:</th><td>{$contactInfo.fieldData.contact_type.name}</td></tr>
+            <tr><th>Permissions:</th><td>{$contactInfo.fieldData.contact_role.name}</td></tr>
+            <tr><th class="glm-nowrap">Display/Moderate/Archive:</th><td>{$contactInfo.fieldData.access.name}</td></tr>
+            <tr><th>Email Address::</th><td>{$contactInfo.fieldData.email}</td></tr>
+            <tr><th>Login Username:</th><td>{$contactInfo.fieldData.username}</td></tr>
+            <tr><th>Login password:</th><td>(not displayed)</td></tr>
+            <tr><th>Alternate Email Address:</th><td>{$contactInfo.fieldData.alt_email}</td></tr>
+            <tr><th>Organization:</th><td>{$contactInfo.fieldData.org}</td></tr>
+            <tr><th>Title/Position:</th><td>{$contactInfo.fieldData.title}</td></tr>
+            <tr><th>Position/Responsibilities:</th><td>{$contactInfo.fieldData.descr}</td>
+            </tr>
+            <tr>
+                <th>Image:</th>
+                <td>
+        {if $contactInfo.fieldData.image}
+                    <img src="{$glmPluginMediaURL}/images/thumb/{$contactInfo.fieldData.image}">
+        {/if} 
+                </td>
+            </tr>
+            <tr><th>Address Line 1:</th><td>{$contactInfo.fieldData.addr1}</td></tr>
+            <tr><th>Address Line 2:</th><td>{$contactInfo.fieldData.addr2}</td></tr>
+            <tr><th>City</th><td>{$contactInfo.fieldData.city.name}</td></tr>
+            <tr><th>State:</th><td>{$contactInfo.fieldData.state.name}</td></tr>
+            <tr><th>ZIP / Postal Code:</th><td>{$contactInfo.fieldData.zip}</td></tr>
+            <tr><th>Country:</th><td>{$contactInfo.fieldData.country.name}</td></tr>
+            <tr>
+                <th>Web Address (URL):</th>
+                <td>
+        {if $contactInfo.fieldData.url}
+                    <a href="http://{$contactInfo.fieldData.url}" target="urlTarget">{$contactInfo.fieldData.url}</a>
+        {/if}
+                </td>
+            </tr>
+            <tr><th>Office Phone #:</th><td>{$contactInfo.fieldData.office_phone}</td></tr>
+            <tr><th>Home Phone #:</th><td>{$contactInfo.fieldData.home_phone}</td></tr>
+            <tr><th>Mobile Phone #:</th><td>{$contactInfo.fieldData.mobile_phone}</td></tr>
+            <tr><th>Alternate Phone #:</th><td>{$contactInfo.fieldData.alt_phone}</td></tr>
+            <tr><th>FAX #:</th><td>{$contactInfo.fieldData.fax}</td></tr>
+        </table>
+    
+    {/if} <!-- mey edit contact -->
+
+        <script type="text/javascript">
+        
+            jQuery(document).ready(function($) {
+                
+                /*
+                 * New City Dialog
+                 */
+    
+                // Setup dialog box for adding a new city
+                $("#newCityDialog").dialog({
+                    autoOpen: false,
+                    minWidth: 400,
+                    dialogClass: "glm-dialog-no-close"
+                });
+                $('#newCityCancel').click( function() {
+                    $("#newCityDialog").dialog("close");
+                });
+                 
+                // Ad a new city button action - pop-up dialog
+                $('#newCityButton').click( function() {
+                    $("#newCityDialog").dialog("open");
+                });
+    
+                // Submit new city
+                var newCityAdded = false;
+                $('#newCitySubmit').click( function() {
+                    
+                    // Get new city name
+                    var newCityName = $('#newCityName').val();
+    
+                    // If no name is supplied, notify used it's required
+                    if (newCityName == '') {
+                        $('#newCityNameTD').addClass('glm-form-bad-input');
+                        $('#newCityNameRequired').text('A city name is required!');
+                        return false;
+                    }
+    
+                    // Add new city name to the hidden field that will pass the new name to PHP.
+                    $('#cityName').val(newCityName);
+                    
+                    // Add new city name to picklist and for storing - Only one permitted per submission
+                    if (newCityAdded) {
+                        
+                        // New city already added, so just update the name and select that one
+                        $('#city').val(-1);
+                        $('#city option:selected').text(newCityName);
+                        
+                    } else {
+                        
+                        // Add the new city name to the city picklist
+                        $('#city').append('<option value="-1">' + newCityName + '</option>');
+                        $('#city').val(-1);
+                        $('#newCityNameTD').append('<input type="hidden" name="newCity" value="' + newCityName + '">');
+                        newCityAdded = true;
+    
+                    }
+          
+                    // Clear new city name from form
+                    $('#newCityName').val('');
+                    
+                    $("#newCityDialog").dialog("close");
+    
+                });
+    
+                /*
+                 * Large Image Dialog
+                 */
+    
+                // Setup dialog box for showing enlarged image image
+                x = $('#largeImageDialog').dialog({
+                    autoOpen: false,
+                    resizable: false,
+                    dialogClass: "glm-dialog-no-close"
+                });
+                $('#largeImageCancel').click( function() {
+                    $('#largeImageDialog').dialog("close");
+                });
+    
+                // Show large image - pop-up dialog - resize at time of pop-up
+                $('#largeImageButton').click( function() {
+                    $("#largeImageDialog").dialog("open");
+                    $( "#largesImageDialog" ).dialog( "option", "position", { my: "center", at: "center", of: window } );
+                    var newWidth = $(window).width() * .8;
+                    $( "#largeImageDialog" ).dialog( "option", "width", newWidth );
+                });
+    
+                // Resize whenever window size changes
+                $(window).resize(function(){
+                    $( "#largeImageDialog" ).dialog( "option", "position", { my: "center", at: "center", of: window } );
+                    var newWidth = $(window).width() * .8;
+                    $( "#largeImageDialog" ).dialog( "option", "width", newWidth );
+                });
+                
+                // 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>
+
+{include file='admin/footer.html'}
diff --git a/views/admin/sample/header.html b/views/admin/sample/header.html
new file mode 100644 (file)
index 0000000..f9fdb91
--- /dev/null
@@ -0,0 +1,5 @@
+<div class="wrap">
+       
+    <h2>{$glmPluginName}</h2>
+    
+  
\ No newline at end of file
diff --git a/views/admin/sample/index.html b/views/admin/sample/index.html
new file mode 100644 (file)
index 0000000..6159f5d
--- /dev/null
@@ -0,0 +1,7 @@
+{include file='admin/sample/header.html'}
+
+    <h2>A Sample Add-On Menu</h2>
+
+    This is a test
+
+{include file='admin/footer.html'}