From 0c4e241786501211901ef0f3f2bbec8db9f42ab8 Mon Sep 17 00:00:00 2001 From: Laury GvR Date: Thu, 12 Jan 2017 10:33:09 -0500 Subject: [PATCH] Added contact list and contact/county search This plugin now has a shortcode for displaying the contact list and a contact search above it, and a county search to its side. --- classes/data/dataContacts.php | 10 +- css/front.css | 24 + defines.php | 2 +- index.php | 15 +- models/admin/contacts/index.php | 6 +- models/admin/contacts/list.php | 254 +++++++++ models/admin/member/contacts.php | 2 +- models/front/contacts/list.php | 486 ++++++++++++++++++ models/front/readme.txt | 7 + ..._V0.0.2.sql => create_database_V0.0.3.sql} | 3 +- setup/databaseScripts/dbVersions.php | 3 +- ...se_V0.0.2.sql => drop_database_V0.0.3.sql} | 0 .../update_database_V0.0.2.sql | 14 +- .../update_database_V0.0.3.sql | 20 + setup/frontHooks.php | 84 +++ setup/hooksHelp.html | 91 +--- setup/shortcodes.php | 149 ++++++ setup/validActions.php | 3 + views/admin/contacts/edit.html | 8 + views/front/contacts/header.html | 8 + views/front/contacts/list.html | 209 ++++++++ views/front/error/badAction.html | 45 ++ views/front/error/header.html | 1 + views/front/error/index.html | 41 ++ views/front/footer.html | 4 + 25 files changed, 1395 insertions(+), 94 deletions(-) create mode 100644 css/front.css create mode 100644 models/admin/contacts/list.php create mode 100644 models/front/contacts/list.php create mode 100644 models/front/readme.txt rename setup/databaseScripts/{create_database_V0.0.2.sql => create_database_V0.0.3.sql} (97%) rename setup/databaseScripts/{drop_database_V0.0.2.sql => drop_database_V0.0.3.sql} (100%) create mode 100644 setup/databaseScripts/update_database_V0.0.3.sql create mode 100644 setup/frontHooks.php create mode 100644 setup/shortcodes.php create mode 100644 views/front/contacts/header.html create mode 100644 views/front/contacts/list.html create mode 100644 views/front/error/badAction.html create mode 100644 views/front/error/header.html create mode 100644 views/front/error/index.html create mode 100644 views/front/footer.html diff --git a/classes/data/dataContacts.php b/classes/data/dataContacts.php index 3770b74..6d3b63d 100644 --- a/classes/data/dataContacts.php +++ b/classes/data/dataContacts.php @@ -249,6 +249,13 @@ class GlmDataContacts extends GlmDataAbstract 'use' => 'a' ), + // County + 'county' => array ( + 'field' => 'county', + 'type' => 'text', + 'use' => 'a' + ), + // State 'state' => array ( 'field' => 'state', @@ -589,7 +596,8 @@ class GlmDataContacts extends GlmDataAbstract 'ref_dest' => $savedFields['ref_dest'], 'ref_dest_name' => $savedFields['ref_dest_name'], 'city' => $savedFields['city'], - 'state' => $savedFields['state'] + 'state' => $savedFields['state'], + 'county' => $savedFields['county'] ); $contacts = $this->getList($where, $order, $fieldVals, $idField, $start, $limit); diff --git a/css/front.css b/css/front.css new file mode 100644 index 0000000..bd4449c --- /dev/null +++ b/css/front.css @@ -0,0 +1,24 @@ +#glmContactsSearchContainer, +#glmContactsCountySearchContainer { + max-width: 300px; + padding: 10px; +} +@media (max-width: 1023px) { + #glmContactsSearchSubmit, + #glmContactsSearchContainer, + #glmContactsCountySearchContainer { + clear: both; + margin: 0 auto; + text-align: center; + } +} +@media (min-width: 1024px) { + #glmContactsSearchSubmit, + #glmContactsSearchContainer, + #glmContactsCountySearchContainer { + float: left; + } + #glmContactsSearchSubmit { + margin-top: 30px; + } +} \ No newline at end of file diff --git a/defines.php b/defines.php index f148a72..709f549 100644 --- a/defines.php +++ b/defines.php @@ -22,7 +22,7 @@ $host = getenv('GLM_HOST_ID'); if (trim($host) == '') { $host = 'PRODUCTION'; } -define('GLM_MEMBER_CONTACTS_PLUGIN_HOST', $host); +define('GLM_MEMBERS_CONTACTS_PLUGIN_HOST', $host); // Determine current http/https protocol $pageProtocol = 'http'; diff --git a/index.php b/index.php index 39884e0..0f813ae 100644 --- a/index.php +++ b/index.php @@ -3,7 +3,7 @@ * Plugin Name: GLM Members Database Contacts * Plugin URI: http://www.gaslightmedia.com/ * Description: Gaslight Media Members Database. - * Version: 1.0.15 + * Version: 1.0.16 * Author: Gaslight Media * Author URI: http://www.gaslightmedia.com/ * License: GPL2 @@ -19,7 +19,7 @@ * @package glmMembersDatabaseContacts * @author Gaslight Media * @license http://www.gaslightmedia.com Gaslightmedia - * @version 1.0.15 + * @version 1.0.16 */ /* @@ -33,8 +33,8 @@ * 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.15'); -define('GLM_MEMBERS_CONTACTS_PLUGIN_DB_VERSION', '0.0.2'); +define('GLM_MEMBERS_CONTACTS_PLUGIN_VERSION', '1.0.16'); +define('GLM_MEMBERS_CONTACTS_PLUGIN_DB_VERSION', '0.0.3'); // 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.58'); @@ -108,7 +108,7 @@ function glmMembersContactsMembersMinVerRequired() { echo '

The '.GLM_MEMBERS_CONTACTS_PLUGIN_NAME.' requires that the main GLM Member DB plugin version be no older than ' - .GLM_MEMBERS_CONTACTS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION.' but the current verssion is '.$curVer.'!

+ .GLM_MEMBERS_CONTACTS_PLUGIN_MIN_MEMBERS_REQUIRED_VERSION.' but the current version is '.$curVer.'!

The '.GLM_MEMBERS_CONTACTS_PLUGIN_NAME.' plugin has been de-activated.

'; @@ -127,6 +127,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. */ require_once GLM_MEMBERS_CONTACTS_PLUGIN_SETUP_PATH.'/validActions.php'; +require_once GLM_MEMBERS_CONTACTS_PLUGIN_SETUP_PATH.'/shortcodes.php'; require_once GLM_MEMBERS_CONTACTS_PLUGIN_DB_SCRIPTS.'/dbVersions.php'; function glmMembersRegisterContacts($addOns) { @@ -143,7 +144,9 @@ function glmMembersRegisterContacts($addOns) { 'dbActiveVersionOption' => GLM_MEMBERS_CONTACTS_PLUGIN_ACTIVE_DB_OPTION, 'dbScriptPath' => GLM_MEMBERS_CONTACTS_PLUGIN_DB_SCRIPTS, 'dbVersions' => $GLOBALS['glmMembersContactsDbVersions'] - ) + ), + 'shortcodes' => $GLOBALS['glmMembersContactsShortcodes'], + 'shortcodesDescription' => $GLOBALS['glmMembersContactsShortcodesDescription'] ); // Return the array with our data added diff --git a/models/admin/contacts/index.php b/models/admin/contacts/index.php index 0a4795c..bc4fb4a 100644 --- a/models/admin/contacts/index.php +++ b/models/admin/contacts/index.php @@ -169,7 +169,7 @@ class GlmMembersAdmin_contacts_index extends GlmDataContacts } // If we're coming from the Member Contacts Menu/Tab - if (defined('GLM_CONTACTS_MEMBER_MENU')) { + if (defined('GLM_MEMBERS_CONTACTS_MEMBER_MENU')) { $fromMemberMenu = true; @@ -224,7 +224,7 @@ class GlmMembersAdmin_contacts_index extends GlmDataContacts // If we don't have a member, the get a list of member IDs for selection if (!$haveMember) { - $membersList = $this->Members->geSimpleMemberstList('TRUE', 'name'); + $membersList = $this->Members->getSimpleMembersList('TRUE', 'name'); } $view = 'edit.html'; @@ -729,7 +729,7 @@ class GlmMembersAdmin_contacts_index extends GlmDataContacts $wpUser = new WP_User($contactCheck['wpUserEmail']->ID); $wpUserID = $wpUser->ID; - $contactMembersListd = ''; + $contactMembersList = ''; // If we have a valid WordPress user ID if ($wpUserID) { diff --git a/models/admin/contacts/list.php b/models/admin/contacts/list.php new file mode 100644 index 0000000..382d1a1 --- /dev/null +++ b/models/admin/contacts/list.php @@ -0,0 +1,254 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @version 0.1 + */ + +// Load Contacts data abstract +require_once GLM_MEMBERS_CONTACTS_PLUGIN_CLASS_PATH.'/data/dataContacts.php'; + +/* + * This class performs the work for the default action of the "Contacts" menu + * option, which is to display the contacts dashboard. + * + */ +class GlmContactsAdmin_contacts_list extends GlmDataContacts +{ + + /** + * WordPress Database Object + * + * @var $wpdb + * @access public + */ + public $wpdb; + /** + * Plugin Configuration Data + * + * @var $config + * @access public + */ + public $config; + + /* + * Constructor + * + * This contructor sets up this model. At this time that only includes + * storing away the WordPress data object. + * + * @return object Class object + * + */ + public function __construct ($wpdb, $config) + { + + // Save WordPress Database object + $this->wpdb = $wpdb; + + // Save plugin configuration object + $this->config = $config; + + /* + * Run constructor for contacts data class to setup table and fields array + * + * Since this class is extending GlmDataContacts, it does not need to pass + * $wpdb and $config to it in the constructor. + */ + parent::__construct(false, false); + + } + + /* + * Perform Model Action + * + * This method does the work for this model and returns any resulting data + * + * @return array Status and data array + * + * '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. + * + */ + public function modelAction ($actionData = false) + { + + $where = ' true '; + $filterPending = false; + $filterArchived = false; + $filterFeatured = false; + $haveFilter = false; + $numbDisplayed = false; + $lastDisplayed = false; + $paging = true; + $prevStart = false; + $nextStart = false; + $start = 1; + $limit = 20; // Set to the number of listings per page + $namesList = false; + $enable_contacts = $this->config['settings']['enable_contacts']; + + // Check if this is a request to show archived contacts + if (isset($_REQUEST['filterArchived'])) { + $where .= " AND access = ".$this->config['access_numb']['Archived']; + $filterArchived = true; + $haveFilter = true; + + // If not, don't show them + } else { + $where .= " AND access != ".$this->config['access_numb']['Archived']; + } + + // Check for a text search + if (isset($_REQUEST['text_search']) && trim($_REQUEST['text_search']) != '') { + + $textSearch = addslashes(filter_input(INPUT_POST, 'text_search', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES)); + $where .= " AND T.id in ( + SELECT DISTINCT(contact) + FROM ".GLM_MEMBERS_CONTACTS_PLUGIN_DB_PREFIX."contact_info + WHERE contact_name like '%$textSearch%' + )"; + } + + + // Get count of contacts listed + $contactCount = $this->getStats($where); + + // If the number of contacts is less than a page, don't do paging + if ($contactCount <= $limit) { + $paging = false; + } + + // Get full list of names matching this where clause for search box + $namesList = $this->getIdName($where); + + // Check if we're doing paging + if (isset($_REQUEST['pageSelect'])) { + + // If request is for Next + if ($_REQUEST['pageSelect'][0] == 'N') { + $newStart = $_REQUEST['nextStart'] - 0; + + // Otherwise it must be Previous + } else { + $newStart = $_REQUEST['prevStart'] - 0; + } + + if ($newStart > 0) { + $start = $newStart; + } + } + + // Get a current list of contacts + $listResult = $this->getSimpleMembersList($where, 'name', true, 'id', $start, $limit); + + // Get paging results + $numbDisplayed = $listResult['returned']; + $lastDisplayed = $listResult['last']; + if ($start == 1) { + $prevStart = false; + } else { + $prevStart = $start - $limit; + if ($start < 1) { + $start = 1; + } + } + if ($listResult['returned'] == $limit) { + $nextStart = $start + $limit; + } + + if (GLM_MEMBERS_CONTACTS_PLUGIN_ADMIN_DEBUG_VERBOSE) { + glmContactsAdmin::addNotice($list, 'DataBlock', 'Contact Data'); + } + + // since we're doing paging, we have to break out just the contact data + $list = $listResult['list']; + unset($listResult); + + // If we have list entries - even if it's an empty list + $success = true; + $haveContacts = false; + if ($list !== false) { + + $success = true; + + // If we have any entries + if (count($list) > 0) { + $haveContacts = true; + } + } + + // Determine if current user can add, edit, delete contact data +// $canEdit = current_user_can('glm_contacts_edit'); + + // Add a url for each contact + foreach ($list as $contact) { + $list[$contact['id']]['contact_slug'] = sanitize_title($contact['name']); + } + + // Compile template data + $templateData = array( + 'enable_contacts' => $enable_contacts, + 'haveContacts' => $haveContacts, + 'contacts' => $list, + 'contactCount' => $contactCount, + 'haveFilter' => $haveFilter, + 'filterArchived' => $filterArchived, + 'filterFeatured' => $filterFeatured, + 'filterPending' => $filterPending, + 'numbDisplayed' => $numbDisplayed, + 'lastDisplayed' => $lastDisplayed, + 'paging' => $paging, + 'prevStart' => $prevStart, + 'nextStart' => $nextStart, + 'start' => $start, + 'limit' => $limit, + 'namesList' => $namesList + ); + + // Return status, suggested view, and data to controller + return array( + 'status' => $success, + 'menuItemRedirect' => false, + 'modelRedirect' => false, + 'view' => 'admin/contacts/list.html', + 'data' => $templateData + ); + + } + + +} + +?> diff --git a/models/admin/member/contacts.php b/models/admin/member/contacts.php index bfb67e8..9929080 100644 --- a/models/admin/member/contacts.php +++ b/models/admin/member/contacts.php @@ -14,7 +14,7 @@ */ // Inform the contacts code that we're working from the member area -define('GLM_CONTACTS_MEMBER_MENU', true); +define('GLM_MEMBERS_CONTACTS_MEMBER_MENU', true); // Load the events index require GLM_MEMBERS_CONTACTS_PLUGIN_PATH."/models/admin/contacts/index.php"; diff --git a/models/front/contacts/list.php b/models/front/contacts/list.php new file mode 100644 index 0000000..75f4fcf --- /dev/null +++ b/models/front/contacts/list.php @@ -0,0 +1,486 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @version 0.1 + */ + +// Translation table for [glm-contacts-list] "show" options to configuration parameters +$GLOBALS['showOpts'] = array( + +); + +// Load Contacts data abstract +require_once GLM_MEMBERS_CONTACTS_PLUGIN_CLASS_PATH.'/data/dataContacts.php'; + +/* + * This class performs the work for the default action of the "Contacts" menu + * option, which is to display the contacts dashboard. + * + */ +class GlmMembersFront_contacts_list extends GlmDataContacts +{ + + /** + * WordPress Database Object + * + * @var $wpdb + * @access public + */ + public $wpdb; + /** + * Plugin Configuration Data + * + * @var $config + * @access public + */ + public $config; + + /* + * Constructor + * + * This contructor sets up this model. At this time that only includes + * storing away the WordPress data object. + * + * @return object Class object + * + */ + public function __construct ($wpdb, $config) + { + + // Save WordPress Database object + $this->wpdb = $wpdb; + + // Save plugin configuration object + $this->config = $config; + + // Run constructor for contacts data class + parent::__construct(false, false); + + } + + /* + * Perform Model Action + * + * This method does the work for this model and returns any resulting data + * + * @return array Status and data array + * + * 'status' + * + * True if successful 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 controller 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. + * + */ + public function modelAction ($actionData = false) + { + + $view = 'index.html'; + $option = 'list'; + $fromMemberMenu = false; + $loggedInMember = false; + $refType = false; + $refTypeName = false; + $haveMember = false; + $this->memberID = false; + $memberData = false; + $memberName = false; + $membersList = false; + $contactsList = false; + $haveContacts = false; + $contactID = false; + $contactInfo = false; + $newContactEmailExists = false; + $newContactUsernameExists = false; + $misMatchedWpUsers = false; + $newContactCreated = false; + $usingExistingWPContact = false; + $usernameChangedToWP = false; + $contactUpdated = false; + $filterArchived = false; + $filterText = false; + $countySearch = false; + $countyList = array(); + $haveFilter = false; + $userDeleted = false; + $wpUserDeleted = false; + $contactMembers = array(); + + $numbContacts = false; + $numbDisplayed = false; + $lastDisplayed = false; + $paging = true; + $prevStart = false; + $nextStart = false; + $start = 1; + $limit = 20; // Set to the number of listings per page + $namesList = false; + + $where = ''; + + $validOptions = array( + 'create', + 'addNew', + 'edit', + 'submit', + 'delete', + 'list' + ); + + // If this is a logged in member user, then show their contacts only + if (isset($this->config['loggedInUser']['contactUser'])) { + + // if there's logged in contact user + $contactUser = $this->config['loggedInUser']['contactUser']; + if ($contactUser['ref_type'] = $this->config['ref_type_numb']['Member'] + && $contactUser['ref_dest'] ) { + + $loggedInMember = true; + + // Filter all contact searches to their member contacts + $where .= " AND ref_type = ".$this->config['ref_type_numb']['Member']." + AND ref_dest = ".$contactUser['ref_dest']; + + // Also set their member as the current one + $this->memberID = $contactUser['ref_dest']; + } + + } + + // If we're coming from the Member Contacts Menu/Tab + if (defined('GLM_MEMBERS_CONTACTS_MEMBER_MENU')) { + + $fromMemberMenu = true; + + // Check if we've received member ID + if (isset($_REQUEST['member'])) { + + // Clean up the member ID and store it in wordpress option + $this->memberID = $_REQUEST['member']-0; + update_option('glmMembersDatabaseMemberID', $this->memberID); + + // Otherwise check if a member is stored in wordpress option + } else { + $this->memberID = get_option('glmMembersDatabaseMemberID', false); + } + + } + + // Load members data class + require_once GLM_MEMBERS_PLUGIN_CLASS_PATH.'/data/dataMembers.php'; + $this->Members = new GlmDataMembers($this->wpdb, $this->config); + + // If we have a member ID - Get Member information + if ($this->memberID) { + $memberData = $this->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']; + } + + // Make sure option is set to list + $option = 'list'; + + $where = ' TRUE '; + + // Only list member contacts for the selected member + if ($haveMember) { + $where .= " AND ref_type = ".$this->config['ref_type_numb']['Member'].' AND ref_dest = '.$this->memberID; + } + + // Filter by selected county + if (isset($_REQUEST['countySearch'])) { + $countySearch = esc_sql($_REQUEST['countySearch']); + $where .= " AND ( + county LIKE '%$countySearch%' + )"; + $haveFilter = true; + } + + // Filter by text string supplied + if (isset($_REQUEST['filterText'])) { + $filterText = esc_sql($_REQUEST['filterText']); + $where .= " AND ( + lname LIKE '%$filterText%' OR + fname LIKE '%$filterText%' OR + org LIKE '%$filterText%' OR + descr LIKE '%$filterText%' OR + county LIKE '%$filterText%' OR + ref_dest IN (SELECT id FROM " . GLM_MEMBERS_PLUGIN_DB_PREFIX . "members WHERE name LIKE '%$filterText%') + )"; + $haveFilter = true; + } + + // Get the total number of contacts listed + $numbContacts = $this->getStats($where); + + // If the number of events is less than a page, don't do paging + if ($numbContacts <= $limit) { + $paging = false; + } + + // Get full list of names matching this where clause for search box + $namesList = $this->getIdName($where); + + // Check if we're doing paging + if (isset($_REQUEST['pageSelect'])) { + + // If request is for Next + if ($_REQUEST['pageSelect'][0] == 'N') { + $newStart = $_REQUEST['nextStart'] - 0; + + // Otherwise it must be Previous + } else { + $newStart = $_REQUEST['prevStart'] - 0; + } + + if ($newStart > 0) { + $start = $newStart; + } + } + + // Get list of contacts + $contactsList = $this->getList($where); + + if ($contactsList != false) { + if ($paging) { + //Get paging results + $numbDisplayed = $contactsList['returned']; + $lastDisplayed = $contactsList['last']; + if ($start == 1) { + $prevStart = false; + } else { + $prevStart = $start - $limit; + if ($start < 1) { + $start = 1; + } + } + if ($contactsList['returned'] == $limit) { + $nextStart = $start + $limit; + } + + } + if (count($contactsList) > 0) { + $haveContacts = true; + } + } + + // Get a list of counties + $countyList = $this->wpdb->get_col("SELECT DISTINCT county FROM ".GLM_MEMBERS_CONTACTS_PLUGIN_DB_PREFIX . "contacts WHERE active = true;"); +// +// +// +// $r = array( +// 'contactRole' => $contactRole, +// 'wpRole' => $this->config['contact_role_wordpress'][$contactRole] +// ); +// +// return $r; + + + // If the option is "edit" don't let lower-level users assign privileges above the user's pay grade + if (($option == 'edit' || $option == 'create') && $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($contactInfo['fieldData']['contact_role']['list'][$this->config['contact_role_numb']['MembersManager']]); + } + + } + + + //echo "
" . print_r($countyList, true) . "
"; + + // Compile template data + $templateData = array( + 'option' => $option, + 'loggedInMember' => $loggedInMember, + 'fromMemberMenu' => $fromMemberMenu, + 'haveMember' => $haveMember, + 'memberID' => $this->memberID, + 'memberData' => $memberData, + 'memberName' => $memberName, + 'membersList' => $membersList, + 'refType' => $refType, + 'refTypeName' => $refTypeName, + 'haveContacts' => $haveContacts, + 'contactsList' => $contactsList, + 'numbContacts' => $numbContacts, + 'contactID' => $contactID, + 'contactInfo' => $contactInfo, + 'newContactEmailExists' => $newContactEmailExists, + 'newContactUsernameExists' => $newContactUsernameExists, + 'misMatchedWpUsers' => $misMatchedWpUsers, + 'usernameChangedToWP' => $usernameChangedToWP, + 'newContactCreated' => $newContactCreated, + 'usingExistingWPContact' => $usingExistingWPContact, + 'contactUpdated' => $contactUpdated, + 'filterArchived' => $filterArchived, + 'filterText' => $filterText, + 'countyList' => $countyList, + 'countySearch' => $countySearch, + 'haveFilter' => $haveFilter, + 'userDeleted' => $userDeleted, + 'wpUserDeleted' => $wpUserDeleted, + 'contactMembers' => $contactMembers, + + 'numbDisplayed' => $numbDisplayed, + 'lastDisplayed' => $lastDisplayed, + 'paging' => $paging, + 'prevStart' => $prevStart, + 'nextStart' => $nextStart, + 'start' => $start = 1, + 'limit' => $limit, + 'namesList' => $namesList, + 'EntityManagerRole' => $this->config['contact_role_numb']['EntityManager'] + + ); + + // Return status, any suggested view, and any data to controller + return array( + 'status' => true, + 'modelRedirect' => false, + 'view' => 'front/contacts/list.html', + 'data' => $templateData + ); + + } + + /* + * Check for new Cities being submitted + * + * @return void + */ + public function checkNewCities($contactID) + { + + // If we have a contact ID and this was a submission with a new city (id < 0) + if ($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_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 contact record + $sql = " + UPDATE ".GLM_MEMBERS_CONTACTS_PLUGIN_DB_PREFIX."contacts + SET city = $cID + WHERE id = ".$contactID." + ;"; + $this->wpdb->query($sql); + + // Update submitted city value to use the new ID + $_REQUEST['city'] = $cID; + + } + } + } + + /* + * Check for additional Members this contact can access + * + * @param $contactInfo array Contact information array + * @param $memberID integer ID of contact's member + * + * @return array Array of Member IDs with names + */ + public function checkContactMembers($contactInfo, $update = false) + { + + // Attempt to get WordPress user data + $contactCheck = $this->checkContact($contactInfo['fieldData']['email']); + $wpUser = new WP_User($contactCheck['wpUserEmail']->ID); + $wpUserID = $wpUser->ID; + + $contactMembersListd = ''; + + // If we have a valid WordPress user ID + if ($wpUserID) { + + // If there's an update request and the current user can manage members + if (apply_filters('glm_members_menu_members', $update)) { + + // And if there's contact member data + if ($_REQUEST['contactMembers'] && count($_REQUEST['contactMembers'])) { + + // Update the contact members selection + $contactMembersList = implode(',', $_REQUEST['contactMembers']); + } + + } else { + + // Get contact's list of members they can manage + $contactMembersList = get_user_meta($wpUserID, 'glmMembersContactMembers', true); + + } + + } + + // Always add the user's primary member to the list + if ($contactMembersList != '') { + $contactMembersList .= ','; + } + $contactMembersList .= $this->memberID; // Always include contact's main member + + // Store the list of ID's for members this user can access in user meta data + update_user_meta($wpUserID, 'glmMembersContactMembers', $contactMembersList); + + // Get a list of contact members with names and other basic info from the list of ids + $contactMembers = $this->Members->getIdName("ID in (".$contactMembersList.")"); + + // Get currently selected member, if not set yet set it to their primary member + $currentContactMember = get_user_meta($wpUserID, 'glmMembersContactMemberSelected', true); + if (empty($currentContactMember)) { + update_user_meta($wpUserID, 'glmMembersContactMemberSelected', $this->memberID); + } + + // Set currently selected member as active + if (isset($contactMembers[$currentContactMember])) { + $contactMembers[$currentContactMember]['selected'] = true; + } + + return $contactMembers; + + } +} + +?> diff --git a/models/front/readme.txt b/models/front/readme.txt new file mode 100644 index 0000000..4c54852 --- /dev/null +++ b/models/front/readme.txt @@ -0,0 +1,7 @@ +The front controller executes models under this directory. + +Typically you should add a directory here that matches the category of actions that will take place. + +Under that directory place the model for the various actions. + +Actions under this directory would normally be called due to processing of a shortcode. \ No newline at end of file diff --git a/setup/databaseScripts/create_database_V0.0.2.sql b/setup/databaseScripts/create_database_V0.0.3.sql similarity index 97% rename from setup/databaseScripts/create_database_V0.0.2.sql rename to setup/databaseScripts/create_database_V0.0.3.sql index 7ebc255..b74ad14 100644 --- a/setup/databaseScripts/create_database_V0.0.2.sql +++ b/setup/databaseScripts/create_database_V0.0.3.sql @@ -1,6 +1,6 @@ -- Gaslight Media Members Database -- File Created: 12/09/14 15:27:15 --- Database Version: 0.0.2 +-- Database Version: 0.0.3 -- Database Creation Script - Contacts Add-On -- -- To permit each query below to be executed separately, @@ -25,6 +25,7 @@ CREATE TABLE {prefix}contacts ( image TINYTEXT NULL, -- Image addr1 TINYTEXT NULL, -- Address line 1 - Address is for contact, not necessarily for organization addr2 TINYTEXT NULL, -- Address line 2 + county TINYTEXT NULL, -- County city INT NULL, -- Pointer to city in cities table state TINYTEXT NULL, -- Two character state code - matches states.ini entries country TINYTEXT NULL, -- Two character country code - matches countries.ini entries diff --git a/setup/databaseScripts/dbVersions.php b/setup/databaseScripts/dbVersions.php index 6c142f5..8eff965 100644 --- a/setup/databaseScripts/dbVersions.php +++ b/setup/databaseScripts/dbVersions.php @@ -28,7 +28,8 @@ */ $glmMembersContactsDbVersions = array( '0.0.1' => array('version' => '0.0.1', 'tables' => 1, 'date' => '4/15/2016'), - '0.0.2' => array('version' => '0.0.2', 'tables' => 1, 'date' => '7/25/2016') + '0.0.2' => array('version' => '0.0.2', 'tables' => 1, 'date' => '7/25/2016'), + '0.0.3' => array('version' => '0.0.3', 'tables' => 1, 'date' => '1/11/2017') ); diff --git a/setup/databaseScripts/drop_database_V0.0.2.sql b/setup/databaseScripts/drop_database_V0.0.3.sql similarity index 100% rename from setup/databaseScripts/drop_database_V0.0.2.sql rename to setup/databaseScripts/drop_database_V0.0.3.sql diff --git a/setup/databaseScripts/update_database_V0.0.2.sql b/setup/databaseScripts/update_database_V0.0.2.sql index 6e333e1..f0fc44d 100644 --- a/setup/databaseScripts/update_database_V0.0.2.sql +++ b/setup/databaseScripts/update_database_V0.0.2.sql @@ -1,20 +1,10 @@ -- Gaslight Media Members Database - Contacts Add-On -- File Created: 12/09/14 15:27:15 --- Database Version: 0.0.2 +-- Database Version: 0.0.3 -- Database Update From Previous Version Script -- -- To permit each query below to be executed separately, -- all queries must be separated by a line with four dashses -- Add primary_contact field -ALTER TABLE {prefix}contacts ADD COLUMN primary_contact BOOLEAN; - ----- - --- Update primary_contacts to default all current entries to false -UPDATE {prefix}contacts SET primary_contact = false; - - - - - +ALTER TABLE {prefix}contacts ADD COLUMN county TINYTEXT; diff --git a/setup/databaseScripts/update_database_V0.0.3.sql b/setup/databaseScripts/update_database_V0.0.3.sql new file mode 100644 index 0000000..e17e1d6 --- /dev/null +++ b/setup/databaseScripts/update_database_V0.0.3.sql @@ -0,0 +1,20 @@ +-- Gaslight Media Members Database - Contacts Add-On +-- File Created: 12/09/14 15:27:15 +-- Database Version: 0.0.3 +-- Database Update From Previous Version Script +-- +-- To permit each query below to be executed separately, +-- all queries must be separated by a line with four dashses + +-- Add primary_contact field +ALTER TABLE {prefix}contacts ADD COLUMN primary_contact BOOLEAN; + +---- + +-- Update primary_contacts to default all current entries to false +UPDATE {prefix}contacts SET primary_contact = false; + + + + + diff --git a/setup/frontHooks.php b/setup/frontHooks.php new file mode 100644 index 0000000..a121a5f --- /dev/null +++ b/setup/frontHooks.php @@ -0,0 +1,84 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @release frontHooks.php,v 1.0 2014/10/31 19:31:47 cscott Exp $ + * @link http://dev.gaslightmedia.com/ + */ + +/* + * Place Misc Hooks and Filters here. If this file exists, it will be included + * by the add-on main plugin script. + * + * Note that filter and hook callback functions must be included in-line as shown below... + * + * add_filter( 'filter_title', function( $parameter ) { + * // Function code + * }); + * + * *** Also note that parameters will be in the context of the main front controller constructor. *** + */ + +// Add contactslug query var +add_filter('query_vars', function($vars) { + array_push($vars, 'contactslug'); + return $vars; +}); + +if (isset($this->config['addOns']['glm-member-db'])) { + +// // Add content to member listing page - Get it from the existing package listing shortcode +// add_filter('glm-member-db-front-members-list-memberDataBelow', function($content, $id) { +// $contactData = do_shortcode('[glm-members-contact-list member='.$id.' template="member-list" order="title"]'); +// $content .= $contactData; +// return $content; +// }, +// 10, +// 2 +// ); + + // Add internal page content links to member detail page +// add_filter('glm-member-db-front-members-detail-linksBottom', function($content, $id) { +// $contactData = do_shortcode('[glm-members-contact-list member='.$id.', template="contacts-link" order="title"]'); +// $content .= $contactData; +// return $content; +// }, +// 10, +// 2 +// ); + + // Add content to member detail page - Get it from the existing package listing shortcode +// add_filter('glm-member-db-front-members-detail-descriptionAfter', function($content, $id) { +// $contactData = do_shortcode('[glm-members-contact-list member='.$id.', template="member-detail" order="title"]'); +// $content .= $contactData; +// return $content; +// }, +// 10, +// 2 +// ); +// +// add_filter('glm-member-db-front-members-detail-sidemenuBottom', function($content, $id) { +// $contactData = do_shortcode('[glm-members-contact-list member='.$id.', template="detail-sidemenu" order="title"]'); +// $content .= $contactData; +// return $content; +// }, +// 10, +// 2 +// ); + +} + +add_filter( 'glm-member-db-contacts-get-contact-data', function( $contact_id ){ + require_once GLM_MEMBERS_EVENTS_PLUGIN_CLASS_PATH . '/data/dataContacts.php'; + $contactData = new GlmDataContacts( $this->wpdb, $this->config ); + $contacts = $contactData->getEntry( $contact_id ); + return $contacts; +} ); + diff --git a/setup/hooksHelp.html b/setup/hooksHelp.html index 6c80f55..865bc48 100644 --- a/setup/hooksHelp.html +++ b/setup/hooksHelp.html @@ -8,40 +8,31 @@ glm_members_permit_admin_member_contacts_tab Filter - - Hook to test if the logged in user is permitted to see the member Contacts tab. - + Hook to test if the logged in user is permitted to see the member Contacts tab. glm_members_permit_admin_member_contacts_add_contact Filter - - Hook to test if the logged in user is permitted to add a new contact. - + Hook to test if the logged in user is permitted to add a new contact. glm_members_permit_admin_member_contacts_view_contact Filter - - Hook to test if the logged in user is permitted to view a contact. - + Hook to test if the logged in user is permitted to view a contact. glm_members_permit_admin_member_contacts_edit_contact Filter - - Hook to test if the logged in user is permitted to edit a contact. - + Hook to test if the logged in user is permitted to edit a contact. glm_members_current_logged_in_user Filter - - Filter that returns the current WordPress user data along with any + Filter that returns the current WordPress user data along with any current Member Contact user information. The information returned is listed below
Array
@@ -82,145 +73,109 @@
             glm_members_locked_to_member_id
             Filter
             
-            
-                Filter that provides the member ID of any member the current user is locked into.
-            
+            Filter that provides the member ID of any member the current user is locked into.
         
         
             glm_members_menu_members
             Filter
             
-            
-                Returns boolean answer to "Can current user access any member?"
-            
+            Returns boolean answer to "Can current user access any member?"
         
         
             glm_members_permit_admin_members_index_member_config_warning
             Filter
             
-            
-                Returns boolean answer to "Should we display configuration warnings to current user?"
-            
+            Returns boolean answer to "Should we display configuration warnings to current user?"
         
         
             glm_members_permit_admin_members_index_add_member
             Filter
             
-            
-                Returns boolean answer to "Can current user edit any member?"
-            
+            Returns boolean answer to "Can current user edit any member?"
         
         
             glm_members_permit_admin_member_index_add_member_info_version
             Filter
             
-            
-                Returns boolean answer to "Should current user see the member information display and add-new links/buttons?"
-            
+            Returns boolean answer to "Should current user see the member information display and add-new links/buttons?"
         
         
             glm_members_permit_admin_member_index_edit_member
             Filter
             
-            
-                Returns boolean answer to "Should current user see the member edit page?" (if not, then just show the info)
-             
+            Returns boolean answer to "Should current user see the member edit page?" (if not, then just show the info)
         
         
             glm_members_permit_admin_member_index_view_member_info_version
             Filter
             
-            
-                Returns boolean answer to "Should current user see link to view/edit member information?"
-            
+            Returns boolean answer to "Should current user see link to view/edit member information?"
         
         
             glm_members_permit_admin_member_index_clone_activate_info_version
             Filter
             
-            
-                Returns boolean answer to "Should current user see Clone and Activate buttons for member information?"
-            
+            Returns boolean answer to "Should current user see Clone and Activate buttons for member information?"
         
         
             glm_members_permit_admin_member_contacts_tab
             Filter
             
-            
-                Returns boolean answer to "Should current user see the Contacts tab?"
-            
+            Returns boolean answer to "Should current user see the Contacts tab?"
         
         
             glm_members_permit_admin_member_contacts_add_contact
             Filter
             
-            
-                Returns boolean answer to "Should current user be able to add contacts?"
-            
+            Returns boolean answer to "Should current user be able to add contacts?"
         
         
             glm_members_permit_admin_member_contacts_view_contact
             Filter
             
-            
-                Returns boolean answer to "Should current user be able to view contact data?"
-            
+            Returns boolean answer to "Should current user be able to view contact data?"
         
         
             glm_members_permit_admin_member_contacts_edit_contact
             Filter
             
-            
-                Returns boolean answer to "Should current user be able to edit contact data?"
-            
+            Returns boolean answer to "Should current user be able to edit contact data?"
         
         
             glm_members_permit_admin_widget_members
             Filter
             
-            
-                Returns boolean answer to "Should current user see the member search and member list in dashboard widget?"
-            
+            Returns boolean answer to "Should current user see the member search and member list in dashboard widget?"
         
         
             glm_members_permit_admin_widget_warnings
             Filter
             
-            
-                Returns boolean answer to "Should current user see warnings in dashboard widget?"
-            
+            Returns boolean answer to "Should current user see warnings in dashboard widget?"
         
         
             glm_members_permit_admin_widget_pending_info
             Filter
             
-            
-                Returns boolean answer to "Should current user see pending member information list in dashboard widget?"
-            
+            Returns boolean answer to "Should current user see pending member information list in dashboard widget?"
         
         
             glm_members_permit_admin_member_index_list_inactive_info
             Filter
             
-            
-                Returns boolean answer to "Should current user see inactive member information records in member info list?"
-            
+            Returns boolean answer to "Should current user see inactive member information records in member info list?"
         
         
             glm_members_permit_admin_member_info_edit
             Filter
             
-            
-                Returns boolean answer to "Should current user be able to edit member information records?"
-            
+            Returns boolean answer to "Should current user be able to edit member information records?"
         
         
             glm_members_permit_admin_profile_index_edit_profile
             Filter
             
-            
-                Returns boolean answer to "Should current user be able to edit own contact profile?"
-            
+            Returns boolean answer to "Should current user be able to edit own contact profile?"
         
         
 
diff --git a/setup/shortcodes.php b/setup/shortcodes.php
new file mode 100644
index 0000000..7fbfc24
--- /dev/null
+++ b/setup/shortcodes.php
@@ -0,0 +1,149 @@
+
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  shortcodes.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/**
+ * Array of short-code
+ *
+ * This array lists all of the short-codes available from the main
+ * member plugin and all add-ons that provide short-code features.
+ *
+ * This array is merged with the data from any registered add-ons
+ * providing short-code features. The plugin providing the short-code
+ * is designated in the 'plugin' elemeent.
+ *
+ * A shortcode is unique to a particular plugin. To provide additional
+ * data and features to a short-code, an add-on should use filters
+ * provided by the short-code to insert data into the template array,
+ * to insert additional format into the template, or to insert
+ * text directly into the completed template output.
+ *
+ * The "attributes" array is a list of available attributes for this
+ * shortcode and their default values. If a database table is provided,
+ * then the value for each attribute is a table column where we get
+ * the default value. If no table is provided, then the value for
+ * each attribute is the actual default value for that attribute.
+ * In the case that the data is taken from the database table, the
+ * "id" for the table entry where the data is stored is assumed to
+ * be 1.
+ *
+ * Note that if the value for a particular attribute is false, then
+ * it is not read from the database even if the table is specified
+ * but might be supplied at run-time as an attribute in the short-code.
+ * All attributes that might be specified in the shortcode must be
+ * listed in the 'attributes' array below. If an attribute is not
+ * specified here, it can't be read from the short-code.
+ *
+ * The following is an explanation of this array.
+ *
+ * array(
+ *      '{shortcode-slug} => array(
+ *          'plugin' => '{plugin (add-on) slug}',       // Identifies which plugin is providing the short-code
+ *          'menu' => '{menu name}',                    // Menu name in this context is simply where to find the action
+ *          'action' => '{shortcode action name},       // Action used to execute this shortcode
+ *          'table' => '{table prefix}{table name}',    // Database table where default attribute values are stored
+ *          'attributes' => array(                      // An array of all shortcode attributes (options)
+ *              '{attr name}' => '{field name}',        // Available attribute names and the database field names with the default value
+ *              ....
+ *          ),
+ *      ... additional short-codes
+ * )
+ *
+ * Shortcode descriptions events
+ *
+ *  
+ *       [glm-members-contacts-shortcode]
+ *        
+ *       
+ *           

+ * Displays something related to this add-on. + *

+ * + * + * + *   + * type="{types}" + * + *

+ * The "type" attribute is used to select the type of data to be displayed. + * Below is a list of available list types. + *

+ *

+ * + * + * + * + *
List Types
oneType One
twoType Two
+ *

+ * + * + * + * + */ + +$glmMembersContactsShortcodes = array( + 'glm-members-contacts-list' => array( + 'plugin' => GLM_MEMBERS_CONTACTS_PLUGIN_SLUG, + 'menu' => 'contacts', + 'action' => 'list', + 'table' => false, + 'attributes' => array( + 'type' => 'all', + 'order' => 'title', + 'member' => false, + 'template' => false, + 'limit' => null, + ) + ), +); + +$glmMembersContactsShortcodesDescription = ' + ShortcodeAttributeDescription + + [glm-members-contacts-list] +   + + Displays a list of contacts. + + + +   + + order="{ fieldName }" + + + The "order" attribute is used to set the field to use for ordering results. Defaults to \'title\'. + + + +   + + template="{ template }" + + + The "template" attribute is used to set the template that will be + used for smarty. Defaults to false. + + + +   + + limit="{ (number) }" + + + The "limit" attribute limits the results to (number). Defaults to null. + + +'; + diff --git a/setup/validActions.php b/setup/validActions.php index 5b81d50..449c702 100644 --- a/setup/validActions.php +++ b/setup/validActions.php @@ -52,6 +52,9 @@ $glmMembersContactsAddOnValidActions = array( ) ), 'frontActions' => array( + 'contacts' => array( + 'list' => GLM_MEMBERS_CONTACTS_PLUGIN_SLUG, + ) ) ); diff --git a/views/admin/contacts/edit.html b/views/admin/contacts/edit.html index 2f40526..3d4698c 100644 --- a/views/admin/contacts/edit.html +++ b/views/admin/contacts/edit.html @@ -371,6 +371,13 @@ + + County: + + + {if $contactInfo.fieldFail.county}

{$contactInfo.fieldFail.county}

{/if} + + State: @@ -544,6 +551,7 @@ Address Line 1:{$contactInfo.fieldData.addr1} Address Line 2:{$contactInfo.fieldData.addr2} City{$contactInfo.fieldData.city.name} + County{$contactInfo.fieldData.county} State:{$contactInfo.fieldData.state.name} ZIP / Postal Code:{$contactInfo.fieldData.zip} Country:{$contactInfo.fieldData.country.name} diff --git a/views/front/contacts/header.html b/views/front/contacts/header.html new file mode 100644 index 0000000..3be1c2f --- /dev/null +++ b/views/front/contacts/header.html @@ -0,0 +1,8 @@ +
+

All Contacts

+ +
+ + \ No newline at end of file diff --git a/views/front/contacts/list.html b/views/front/contacts/list.html new file mode 100644 index 0000000..b3bcf50 --- /dev/null +++ b/views/front/contacts/list.html @@ -0,0 +1,209 @@ + + + + + Contacts List + + + + +{include file='front/contacts/header.html'} + +
+ + + + +
+
+
+ Text Search: +
+
+ County Search: + +
+
+ +
+
+
+ + +
+ +

Total found: {$numbContacts}  

+ + {if $paging} + + + {/if} + + + {if $haveContacts} + {foreach $contactsList as $contact} +
+
+
+

+ {if $fromMemberMenu} + {$contact.lname}, {$contact.fname} + {else} + {$contact.lname}, {$contact.fname} + {/if} +

+ +
+ +
+ {if $contact.title}
{$contact.title}
{/if} + {if $contact.ref_type.name} +
+ {if $contact.ref_dest_name} + {$contact.ref_dest_name} + {/if} +
+ {/if} + {if $contact.addr1}
{$contact.addr1}
{/if} + {if $contact.addr2}
{$contact.addr2}
{/if} + {if $contact.zip or $contact.city.name or $contact.state.name} +
+ {if $contact.city.name}{$contact.city.name},{/if} + {if $contact.state.name}{$contact.state.name}{/if} + {if $contact.zip}{$contact.zip}{/if} +
{/if} + {if $contact.county}
{$contact.county}
{/if} +
+
+ {if $contact.office_phone}
{$contact.office_phone}
{/if} + {if $contact.fax}
{$contact.fax}
{/if} + {if $contact.email}
Email: {$contact.email}
{/if} +
+ + + + +
+ + + + +
+ +
+
+
+
+ {/foreach} + {else} + (no contacts listed) + {/if} + {if $paging} + + + {/if} +
+ + + + + + + + + + + + + +{include file='front/footer.html'} + + + \ No newline at end of file diff --git a/views/front/error/badAction.html b/views/front/error/badAction.html new file mode 100644 index 0000000..50c1f71 --- /dev/null +++ b/views/front/error/badAction.html @@ -0,0 +1,45 @@ +{include file='front/error/header.html'} +
+
+

Aw shucks!

+

We couldn't get you the page you wanted.

+
+

+ Yes, something went wrong, but we really want to make it right. In fact, we've already + notified our hard-working Web crew that you had this problem and will do what we can + to make sure it doesn't happen again. +

+

+ As far as we can tell now, an invalid action has been requested. This really shouldn't + happen, so we're going to research this to see if we can avoid this in the future. +

+ {if isset($errorMsg) && $errorMsg} +

Oh, we have a little more information for you.

+

{$errorMsg}

+ {/if} + +

+ Please head back to the link below and try again. If you continue to get this error, + please call for assistance. +

+

Return to Home Page

+
+
+ + + + +{include file='front/footer.html'} + diff --git a/views/front/error/header.html b/views/front/error/header.html new file mode 100644 index 0000000..71bb229 --- /dev/null +++ b/views/front/error/header.html @@ -0,0 +1 @@ +
diff --git a/views/front/error/index.html b/views/front/error/index.html new file mode 100644 index 0000000..5c41aad --- /dev/null +++ b/views/front/error/index.html @@ -0,0 +1,41 @@ +{include file='front/error/header.html'} +
+
+

Aw shucks!

+

We couldn't get you the page you wanted.

+
+

+ Yes, something went wrong, but we really want to make it right. In fact, we've already + notified our hard-working Web crew that you had this problem and will do what we can + to make sure it doesn't happen again. +

+ {if isset($errorMsg) && $errorMsg} +

Oh, we have a little more information for you.

+

{$errorMsg}

+ {/if} + +

+ Please head back to the link below and try again. If you continue to get this error, + please call for assistance. +

+

Return to Home Page

+
+
+ + + + +{include file='front/footer.html'} + diff --git a/views/front/footer.html b/views/front/footer.html new file mode 100644 index 0000000..9fb331e --- /dev/null +++ b/views/front/footer.html @@ -0,0 +1,4 @@ + +
+ +
\ No newline at end of file -- 2.17.1