From: Chuck Scott Date: Tue, 22 Oct 2019 21:20:14 +0000 (-0400) Subject: Fixed query for getting events by lat/lon for NearMe X-Git-Url: http://cvs2.gaslightmedia.com/gitweb/index.cgi?a=commitdiff_plain;h=5c937901251bb1e1cf79912e1753e598c47ec420;p=WP-Plugins%2Fglm-member-db-events.git Fixed query for getting events by lat/lon for NearMe --- diff --git a/classes/eventDataByLatLon.php b/classes/eventDataByLatLon.php new file mode 100644 index 0000000..9fddd53 --- /dev/null +++ b/classes/eventDataByLatLon.php @@ -0,0 +1,317 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @version 0.1 + */ + +require_once GLM_MEMBERS_EVENTS_PLUGIN_CLASS_PATH.'/data/dataEvents.php'; + +/* + * This class performs the work for the default action of the "Members" menu + * option, which is to display the members dashboard. + * + */ + +class GlmMembersFront_events_eventDataByLatLon extends GlmDataEvents +{ + + /** + * 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 members data class + parent::__construct(false, false); + + } + + /* + * Perform Model Action + * + * NOTE: This model is intended to be called directly by an add_filter() to + * supply data only. It is not intended to be called by the controller and + * therefore should not be added to the validActions data. + * + * This model receives an array that includes a list of lat/lon boxes to use + * for listing members whose locations are within those boxes. The supplied + * array also may include other listing results passed by other filter hooks + * that should not be removed. The returned member data is expected to be used + * as data for map items along with similar data from other add-ons. + * + * The format of the requet array is as follows... + * + * array( + * // First area to search + * array( + * 'latMax' => {lat at North end of area}, + * 'latMin' => {lat at South end of area}, + * 'lonMax' => {lon at East end of area}, + * 'lonMin' => {lon at West end of area} + * ), + * // Second area to search + * array( + * 'latMax' => {lat at North end of area}, + * 'latMin' => {lat at South end of area}, + * 'lonMax' => {lon at East end of area}, + * 'lonMin' => {lon at West end of area} + * ), + * // Additional areas + * ) + * + * The format of the reply array is as follows... + * + * array( + * array( + * 'type' => {type of item, i.e. 'member', 'event', ...}, + * 'id' => {ID of item for reference}, + * 'lat' => {Latitude}, + * 'lon' => {Longitude}, + * 'name' => {Name of item}, + * 'addr1' => {Address line 1 of location}, + * 'addr2' => {Address line 2 of location}, + * 'city' => {City of location}, + * 'state' => {State code of location}, + * 'zip' => {Postal Code of location}, + * 'phone' => {Contact phone number}, + * 'email' => {Contact E-Mail address}, + * 'url' => {URL of item}, + * 'region' => {Region name, if available}, + * 'categories' => {array of categories - i.e. array( 0 = array( id => {id}, name => {name}), ... ) + * 'descr' => {Description}, + * 'short_descr' => {Short Description}, + * 'detail_page' => {URL of detail page, if available} + * 'dates' => {Text stating date, dates, or date range}, + * 'times' => {Text stating time, times, or time range} + * ), + * {additional results} + * ) + * + * Note that there may be more than one search area supplied. This model must + * return a list that includes any members in any of those search areas. + * + * @param array $search Array of lat/lon boxes to search + * + * @return array Items (see above) - Returns false if total failure. + * + */ + public function modelAction ($request = 'onMap', $search = false, $searchText = '') + { + + $items = array(); + + // Do sanity check on supplied data + if ($request == 'onMap' && (!is_array($search) || count($search) <= 0)) { + return false; + } + + // If this is an "onMap" request build query where clause for each search area - otherwise it's anywhere + $latLonWhereForEventLoc = ''; + $latLonWhereForMembLoc = ''; + if ($request == 'onMap') { + + $latLonWhereForEventLoc = ' AND ( '; + $latLonWhereForMembLoc = ' AND ( '; + $or = ''; + foreach ($search as $area) { + $latLonWhereForEventLoc .= " $or ( (L.lat BETWEEN ".$area['latMin']." AND ".$area['latMax'].") AND (L.lon BETWEEN ".$area['lonMin']." AND ".$area['lonMax'].") ) "; + $latLonWhereForMembLoc .= " $or ( (I.lat BETWEEN ".$area['latMin']." AND ".$area['latMax'].") AND (I.lon BETWEEN ".$area['lonMin']." AND ".$area['lonMax'].") ) "; + $or = 'OR'; + } + $latLonWhereForEventLoc .= ')'; + $latLonWhereForMembLoc .= ')'; + + } + + $textWhere = ''; + if ($searchText != '') { + $textWhere .= " + AND ( + E.name like '%".addslashes($searchText)."%' + OR E.descr like '%".addslashes($searchText)."%' + ) + "; + } + + // Determine first and last dates to display + $dateFrom = date('Y-m-d H:i:s'); + $dateTo = date('Y-m-d H:i:s', strtotime('+1 month')); + + // Get event data for events that use event locations + $sql = " + SELECT E.id, + L.id AS loc_id, + L.lat, + L.lon, + E.name, + L.name AS loc_name, + L.address AS addr1, + '' AS addr2, + C.name AS city, + L.state, + L.zip, + E.contact_phone AS phone, + E.contact_email AS email, + E.url, + R.name AS region, + E.descr, + E.intro AS short_descr + FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."events E, + ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."locations L + LEFT JOIN ".GLM_MEMBERS_PLUGIN_DB_PREFIX."cities C ON C.id = L.city + LEFT JOIN ".GLM_MEMBERS_PLUGIN_DB_PREFIX."regions R ON R.id = L.region + WHERE E.status = 10 + AND L.event = E.id + AND ( + SELECT count(start_time) + FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."times + WHERE event = E.id + AND active + AND (start_time BETWEEN '$dateFrom' AND '$dateTo') + ) + $latLonWhereForEventLoc + $textWhere + + ;"; + $eventsEventLocations = $this->wpdb->get_results($sql, ARRAY_A); + + // Get event data for events that use member locations + $sql = " + SELECT E.id, + I.id as loc_id, + I.lat, + I.lon, + E.name, + I.member_name AS loc_name, + I.addr1, + I.addr2, + C.name AS city, + I.state, + I.zip, + I.phone, + I.email, + I.url, + R.name AS region, + E.descr, + '' AS short_descr + FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."events E, + ".GLM_MEMBERS_PLUGIN_DB_PREFIX."members M, + ".GLM_MEMBERS_PLUGIN_DB_PREFIX."member_info I + LEFT JOIN ".GLM_MEMBERS_PLUGIN_DB_PREFIX."cities C ON C.id = I.city + LEFT JOIN ".GLM_MEMBERS_PLUGIN_DB_PREFIX."regions R ON R.id = I.region + WHERE E.status = 10 + AND E.use_member_location + AND E.ref_type = 10 + AND M.id = E.ref_dest + AND ( ( + E.other_ref_dest + AND I.member = E.other_ref_dest + ) + OR ( + !E.other_ref_dest + AND I.member = E.ref_dest + ) + ) + AND I.status = 10 + AND ( + SELECT count(start_time) + FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."times + WHERE event = E.id + AND active + AND (start_time BETWEEN '$dateFrom' AND '$dateTo') + ) + $latLonWhereForMembLoc + $textWhere + ;"; + + $eventsMemberLocations = $this->wpdb->get_results($sql, ARRAY_A); + + // Merge both arrays into one to simplify further processing + $eventsData = array_merge($eventsEventLocations, $eventsMemberLocations); + + // Rebuild data with correct array format for map items + $events = array(); + if (is_array($eventsData) && count($eventsData) > 0) { + foreach ($eventsData as $k=>$v) { + + // Get any categories for this event + $cats = array(); + $sql = " + SELECT C.id, C.name + FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."categories C, + ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."event_categories E + WHERE E.event = ".$v['id']." + AND C.id = E.category + ;"; + $eventCats = $this->wpdb->get_results($sql, ARRAY_A); + + // Add to results - Key is {type}.{event ID} + $events[$v['id']] = array( + 'type' => 'Event', + 'id' => $v['id'], + 'lat' => $v['lat'], + 'lon' => $v['lon'], + 'name' => $v['name'], + 'loc_name' => $v['loc_name'], + 'addr1' => $v['addr1'], + 'addr2' => $v['addr2'], + 'city' => $v['city'], + 'state' => $v['state'], + 'zip' => $v['zip'], + 'phone' => $v['phone'], + 'email' => $v['email'], + 'url' => $v['url'], + 'region' => $v['region'], + 'categories' => $cats, + 'descr' => $v['descr'], + 'short_descr' => $v['short_descr'], + 'detail_page' => '', + 'dates' => '', + 'times' => '' + ); + } + } + + return $events; + } + + +} + +?> diff --git a/models/front/events/eventDataByLatLon.php b/models/front/events/eventDataByLatLon.php deleted file mode 100644 index c4d5dad..0000000 --- a/models/front/events/eventDataByLatLon.php +++ /dev/null @@ -1,333 +0,0 @@ - - * @license http://www.gaslightmedia.com Gaslightmedia - * @version 0.1 - */ - -require_once GLM_MEMBERS_EVENTS_PLUGIN_CLASS_PATH.'/data/dataEvents.php'; - -/* - * This class performs the work for the default action of the "Members" menu - * option, which is to display the members dashboard. - * - */ - -class GlmMembersFront_events_eventDataByLatLon extends GlmDataEvents -{ - - /** - * 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 members data class - parent::__construct(false, false); - - } - - /* - * Perform Model Action - * - * NOTE: This model is intended to be called directly by an add_filter() to - * supply data only. It is not intended to be called by the controller and - * therefore should not be added to the validActions data. - * - * This model receives an array that includes a list of lat/lon boxes to use - * for listing members whose locations are within those boxes. The supplied - * array also may include other listing results passed by other filter hooks - * that should not be removed. The returned member data is expected to be used - * as data for map items along with similar data from other add-ons. - * - * The format of the requet array is as follows... - * - * array( - * // First area to search - * array( - * 'latMax' => {lat at North end of area}, - * 'latMin' => {lat at South end of area}, - * 'lonMax' => {lon at East end of area}, - * 'lonMin' => {lon at West end of area} - * ), - * // Second area to search - * array( - * 'latMax' => {lat at North end of area}, - * 'latMin' => {lat at South end of area}, - * 'lonMax' => {lon at East end of area}, - * 'lonMin' => {lon at West end of area} - * ), - * // Additional areas - * ) - * - * The format of the reply array is as follows... - * - * array( - * array( - * 'type' => {type of item, i.e. 'member', 'event', ...}, - * 'id' => {ID of item for reference}, - * 'lat' => {Latitude}, - * 'lon' => {Longitude}, - * 'name' => {Name of item}, - * 'addr1' => {Address line 1 of location}, - * 'addr2' => {Address line 2 of location}, - * 'city' => {City of location}, - * 'state' => {State code of location}, - * 'zip' => {Postal Code of location}, - * 'phone' => {Contact phone number}, - * 'email' => {Contact E-Mail address}, - * 'url' => {URL of item}, - * 'region' => {Region name, if available}, - * 'categories' => {array of categories - i.e. array( 0 = array( id => {id}, name => {name}), ... ) - * 'descr' => {Description}, - * 'short_descr' => {Short Description}, - * 'detail_page' => {URL of detail page, if available} - * 'dates' => {Text stating date, dates, or date range}, - * 'times' => {Text stating time, times, or time range} - * ), - * {additional results} - * ) - * - * Note that there may be more than one search area supplied. This model must - * return a list that includes any members in any of those search areas. - * - * @param array $search Array of lat/lon boxes to search - * - * @return array Items (see above) - Returns false if total failure. - * - */ - public function modelAction ($request = 'onMap', $search = false, $searchText = '') - { - - $items = array(); - - // Do sanity check on supplied data - if ($request == 'onMap' && (!is_array($search) || count($search) <= 0)) { - return false; - } - - // If this is an "onMap" request build query where clause for each search area - otherwise it's anywhere - $latLonWhereForEventLoc = ''; - $latLonWhereForMembLoc = ''; - if ($request == 'onMap') { - - $latLonWhereForEventLoc = ' AND ( '; - $latLonWhereForMembLoc = ' AND ( '; - $or = ''; - foreach ($search as $area) { - $latLonWhereForEventLoc .= " $or ( (L.lat BETWEEN ".$area['latMin']." AND ".$area['latMax'].") AND (L.lon BETWEEN ".$area['lonMin']." AND ".$area['lonMax'].") ) "; - $latLonWhereForMembLoc .= " $or ( (I.lat BETWEEN ".$area['latMin']." AND ".$area['latMax'].") AND (I.lon BETWEEN ".$area['lonMin']." AND ".$area['lonMax'].") ) "; - $or = 'OR'; - } - $latLonWhereForEventLoc .= ')'; - $latLonWhereForMembLoc .= ')'; - - } - - $testWhere = ''; - if ($searchText != '') { - $textWhere .= " - AND ( - E.name like '%".addslashes($searchText)."%' - OR E.descr like '%".addslashes($searchText)."%' - ) - "; - } - - // Determine first and last dates to display - $dateFrom = "2016-11-22 00:00:00"; - $dateTo = "2016-11-30 24:59:59"; - - // Get event data for events that use event locations - $sql = " - SELECT E.id, - L.id AS loc_id, - L.lat, - L.lon, - E.name, - L.name AS loc_name, - L.address AS addr1, - '' AS addr2, - C.name AS city, - L.state, - L.zip, - E.contact_phone AS phone, - E.contact_email AS email, - E.url, - R.name AS region, - E.descr, - E.intro AS short_descr - FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."events E, - ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."locations L, - ".GLM_MEMBERS_PLUGIN_DB_PREFIX."cities C, - ".GLM_MEMBERS_PLUGIN_DB_PREFIX."regions R - WHERE E.status = 10 - AND L.event = E.id - AND C.id = L.city - AND R.id = L.region - AND ( - SELECT MIN(start_time) - FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."times - WHERE event = E.id - AND active - ) < '$dateFrom' - AND ( - SELECT MAX(end_time) - FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."times - WHERE event = E.id - AND active - ) > '$dateTo' - $latLonWhereForEventLoc - $textWhere - - ;"; - $eventsEventLocations = $this->wpdb->get_results($sql, ARRAY_A); -//trigger_error(print_r($eventsEventLocations,1), E_USER_NOTICE); - - - // Get event data for events that use member locations - $sql = " - SELECT E.id, - I.id as loc_id, - I.lat, - I.lon, - E.name, - I.member_name AS loc_name, - I.addr1, - I.addr2, - C.name AS city, - I.state, - I.zip, - I.phone, - I.email, - I.url, - R.name AS region, - E.descr, - '' AS short_descr - FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."events E, - ".GLM_MEMBERS_PLUGIN_DB_PREFIX."members M, - ".GLM_MEMBERS_PLUGIN_DB_PREFIX."member_info I, - ".GLM_MEMBERS_PLUGIN_DB_PREFIX."cities C, - ".GLM_MEMBERS_PLUGIN_DB_PREFIX."regions R - WHERE E.status = 10 - AND E.use_member_location - AND E.ref_type = 10 - AND M.id = E.ref_dest - AND ( ( - E.other_ref_dest - AND I.member = E.other_ref_dest - ) - OR ( - !E.other_ref_dest - AND I.member = E.ref_dest - ) - ) - AND I.status = 10 - AND C.id = I.city - AND R.id = I.region - AND ( - SELECT MIN(start_time) - FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."times - WHERE event = E.id - AND active - ) < '$dateFrom' - AND ( - SELECT MAX(end_time) - FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."times - WHERE event = E.id - AND active - ) > '$dateTo' - $latLonWhereForEventLoc - $textWhere - ;"; - - $eventsMemberLocations = $this->wpdb->get_results($sql, ARRAY_A); - - // Merge both arrays into one to simplify further processing - $eventsData = array_merge($eventsEventLocations, $eventsMemberLocations); - - // Rebuild data with correct array format for map items - $events = array(); - if (is_array($eventsData) && count($eventsData) > 0) { - foreach ($eventsData as $k=>$v) { - - // Get any categories for this event - $cats = array(); - $sql = " - SELECT C.id, C.name - FROM ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."categories C, - ".GLM_MEMBERS_EVENTS_PLUGIN_DB_PREFIX."event_categories E - WHERE E.event = ".$v['id']." - AND C.id = E.category - ;"; - $eventCats = $this->wpdb->get_results($sql, ARRAY_A); - - // Add to results - Key is {type}.{event ID} - $events['Event'+$v['id']] = array( - 'type' => 'Event', - 'id' => $v['id'], - 'lat' => $v['lat'], - 'lon' => $v['lon'], - 'name' => $v['name'], - 'loc_name' => $v['loc_name'], - 'addr1' => $v['addr1'], - 'addr2' => $v['addr2'], - 'city' => $v['city'], - 'state' => $v['state'], - 'zip' => $v['zip'], - 'phone' => $v['phone'], - 'email' => $v['email'], - 'url' => $v['url'], - 'region' => $v['region'], - 'categories' => $cats, - 'descr' => $v['descr'], - 'short_descr' => $v['short_descr'], - 'detail_page' => '', - 'dates' => '', - 'times' => '' - ); - } - } - - return $events; - } - - -} - -?> diff --git a/setup/adminHooks.php b/setup/adminHooks.php index 97b7a0c..21ab467 100644 --- a/setup/adminHooks.php +++ b/setup/adminHooks.php @@ -225,7 +225,7 @@ add_filter( add_filter( 'glm-hook-list-map-items-by-latlon', function($data) { // Call dedicated model to perform search - include_once GLM_MEMBERS_EVENTS_PLUGIN_PATH . '/models/front/events/eventDataByLatLon.php'; + include_once GLM_MEMBERS_EVENTS_PLUGIN_PATH . '/classes/eventDataByLatLon.php'; $MapItems = new GlmMembersFront_events_eventDataByLatLon($this->wpdb, $this->config); $mapItems = $MapItems->modelAction($data['request'], $data['area'], $data['filter']); @@ -243,8 +243,3 @@ add_filter( 'glm-hook-list-map-items-by-latlon', function($data) { return $data; }); -add_action( 'init', function(){ - if ( ! session_id() ) { - session_start(); - } -});