diff --git a/admin/admin_settings.php b/admin/admin_settings.php index 4b5cf991..938ed1d2 100644 --- a/admin/admin_settings.php +++ b/admin/admin_settings.php @@ -902,6 +902,26 @@ if ( defined('HESK_DEMO') ) ?> +
+ +
+
    +
'; + ?> +
+
diff --git a/admin/admin_settings_save.php b/admin/admin_settings_save.php index 498dc3f2..52aa1048 100644 --- a/admin/admin_settings_save.php +++ b/admin/admin_settings_save.php @@ -506,6 +506,7 @@ $set['use_bootstrap_theme'] = empty($_POST['use_bootstrap_theme']) ? 0 : 1; $set['new_kb_article_visibility'] = hesk_checkMinMax( intval( hesk_POST('new_kb_article_visibility') ) , 0, 2, 2); $set['mfh_attachments'] = empty($_POST['email_attachments']) ? 0 : 1; $set['show_number_merged'] = empty($_POST['show_number_merged']) ? 0 : 1; +$set['request_location'] = empty($_POST['request_location']) ? 0 : 1; if ($set['customer-email-verification-required']) { @@ -568,7 +569,10 @@ $modsForHesk_settings[\'new_kb_article_visibility\'] = '.$set['new_kb_article_vi $modsForHesk_settings[\'attachments\'] = '.$set['mfh_attachments'].'; //-- Setting for showing number of merged tickets in the ticket search screen. 0 = Disable, 1 = Enable -$modsForHesk_settings[\'show_number_merged\'] = '.$set['show_number_merged'].';'; +$modsForHesk_settings[\'show_number_merged\'] = '.$set['show_number_merged'].'; + +//-- Setting for requesting user\'s location. 0 = Disable, 1 = Enable +$modsForHesk_settings[\'request_location\'] = '.$set['request_location'].';'; // Write the file if ( ! file_put_contents(HESK_PATH . 'modsForHesk_settings.inc.php', $modsForHesk_file_content) ) diff --git a/admin/admin_ticket.php b/admin/admin_ticket.php index d7918c2f..4bf2e0be 100644 --- a/admin/admin_ticket.php +++ b/admin/admin_ticket.php @@ -588,6 +588,15 @@ if (isset($_GET['delatt']) && hesk_token_check()) hesk_process_messages($hesklang['kb_att_rem'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'SUCCESS'); } +//-- Update location action +if (isset($_POST['latitude']) && isset($_POST['longitude'])) { + hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `latitude` = '".hesk_dbEscape($_POST['latitude'])."', + `longitude` = '".hesk_dbEscape($_POST['longitude'])."' WHERE `ID` = ".intval($ticket['id'])); + + //redirect + hesk_process_messages($hesklang['ticket_location_updated'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'SUCCESS'); +} + /* Print header */ require_once(HESK_PATH . 'inc/headerAdmin.inc.php'); @@ -861,6 +870,89 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); { echo ' '; } + if ($modsForHesk_settings['request_location']) + { + $locationText = ''; + $iconColor = ''; + $hasLocation = true; + if (strpos($ticket['latitude'], 'E') === false) + { + $locationText = $hesklang['click_for_map']; + $iconColor = 'inherit'; + } + else + { + $hasLocation = false; + $locationText = $hesklang['location_unavailable']; + $iconColor = '#ccc'; + } + ?> + + + + + + + +
diff --git a/inc/header.inc.php b/inc/header.inc.php index 19fc20ef..656049b5 100644 --- a/inc/header.inc.php +++ b/inc/header.inc.php @@ -60,6 +60,7 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); + @@ -68,6 +69,7 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); + css/bootstrap-iconpicker.min.css" rel="stylesheet"> + @@ -68,6 +69,7 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); + +
+ +
+

+
+
+
+
+ @@ -1002,6 +1015,8 @@ if ( ! isset($_SESSION['c_category']) && ! $hesk_settings['select_cat']) ?>
+ +
@@ -1025,6 +1040,16 @@ if ( ! isset($_SESSION['c_category']) && ! $hesk_settings['select_cat']) + requestUserLocation("'.$hesklang['your_current_location'].'", "'.$hesklang['unable_to_determine_location'].'"); + + '; +} + hesk_cleanSessionVars('iserror'); hesk_cleanSessionVars('isnotice'); diff --git a/install/mods-for-hesk/ajax/uninstall-database-ajax.php b/install/mods-for-hesk/ajax/uninstall-database-ajax.php index d03d06d0..eb975e71 100644 --- a/install/mods-for-hesk/ajax/uninstall-database-ajax.php +++ b/install/mods-for-hesk/ajax/uninstall-database-ajax.php @@ -31,6 +31,8 @@ if ($task == 'status-change') { removeTicketsPendingVerificationTable(); } elseif ($task == 'service-message-icon') { removeServiceMessageCustomIcon(); +} elseif ($task == 'location') { + removeTicketLocation(); } elseif ($task == 'miscellaneous') { executeMiscellaneousSql(); } else { diff --git a/install/mods-for-hesk/js/uninstall-scripts.js b/install/mods-for-hesk/js/uninstall-scripts.js index ce2f3a0d..cd5ce96c 100644 --- a/install/mods-for-hesk/js/uninstall-scripts.js +++ b/install/mods-for-hesk/js/uninstall-scripts.js @@ -1,7 +1,8 @@ function getTasks() { return ['status-change', 'autorefresh', 'parent-child', 'settings-access', 'activate-user', 'notify-note-unassigned', 'user-manage-notification-settings', 'settings-table', 'verified-emails-table', - 'pending-verification-emails-table', 'pending-verification-tickets-table', 'service-message-icon', 'miscellaneous']; + 'pending-verification-emails-table', 'pending-verification-tickets-table', 'service-message-icon', 'location', + 'miscellaneous']; } function processUninstallation() { diff --git a/install/mods-for-hesk/sql/installSql.php b/install/mods-for-hesk/sql/installSql.php index e4997607..97974648 100644 --- a/install/mods-for-hesk/sql/installSql.php +++ b/install/mods-for-hesk/sql/installSql.php @@ -448,6 +448,10 @@ function execute230Scripts() { executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` SET `Key` = `ShortNameContentKey`"); executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` DROP COLUMN `ShortNameContentKey`"); executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` DROP COLUMN `TicketViewContentKey`"); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` ADD COLUMN `latitude` VARCHAR(100) NOT NULL DEFAULT 'E-0'"); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` ADD COLUMN `longitude` VARCHAR(100) NOT NULL DEFAULT 'E-0'"); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."stage_tickets` ADD COLUMN `latitude` VARCHAR(100) NOT NULL DEFAULT 'E-0'"); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."stage_tickets` ADD COLUMN `longitude` VARCHAR(100) NOT NULL DEFAULT 'E-0'"); executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."settings` SET `Value` = '2.3.0' WHERE `Key` = 'modsForHeskVersion'"); } @@ -463,6 +467,13 @@ function execute230FileUpdate() { //-- Setting for showing number of merged tickets in the ticket search screen. 0 = Disable, 1 = Enable $modsForHesk_settings[\'show_number_merged\'] = 1;'; } + if (strpos($file, '$modsForHesk_settings[\'request_location\']') === false) + { + $file .= ' + + //-- Setting for requesting user\'s location. 0 = Disable, 1 = Enable +$modsForHesk_settings[\'request_location\'] = 0'; + } return file_put_contents(HESK_PATH.'modsForHesk_settings.inc.php', $file); } diff --git a/install/mods-for-hesk/sql/uninstallSql.php b/install/mods-for-hesk/sql/uninstallSql.php index d76c7728..9718ab79 100644 --- a/install/mods-for-hesk/sql/uninstallSql.php +++ b/install/mods-for-hesk/sql/uninstallSql.php @@ -136,6 +136,16 @@ function removeServiceMessageCustomIcon() { executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` DROP COLUMN `icon`"); } +function removeTicketLocation() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` DROP COLUMN `latitude`"); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` DROP COLUMN `longitude`"); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."stage_tickets` DROP COLUMN `latitude`"); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."stage_tickets` DROP COLUMN `longitude`"); +} + function executeMiscellaneousSql() { global $hesk_settings; diff --git a/install/mods-for-hesk/uninstallModsForHesk.php b/install/mods-for-hesk/uninstallModsForHesk.php index 1dd3d27c..f06857ce 100644 --- a/install/mods-for-hesk/uninstallModsForHesk.php +++ b/install/mods-for-hesk/uninstallModsForHesk.php @@ -17,6 +17,7 @@ function echoTaskRows() { printUninstallRow('Remove pending verification emails table', 'pending-verification-emails-table'); printUninstallRow('Remove tickets pending verification table', 'pending-verification-tickets-table'); printUninstallRow('Remove custom service messages icon', 'service-message-icon'); + printUninstallRow('Remove ticket location', 'location'); printUninstallRow('Miscellaneous database cleanup changes', 'miscellaneous'); } diff --git a/js/modsForHesk-javascript.js b/js/modsForHesk-javascript.js index a8bc674d..4f66b7d7 100644 --- a/js/modsForHesk-javascript.js +++ b/js/modsForHesk-javascript.js @@ -106,4 +106,102 @@ function changeText(id, checkedValue, uncheckedValue, object) { } } +function requestUserLocation(yourLocationText, unableToDetermineText) { + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(function(position) { + var latitude = position.coords.latitude; + var longitude = position.coords.longitude; + setLatLon(latitude, longitude); + $('#console').hide(); + initializeMapForCustomer(latitude, longitude, yourLocationText); + }, function(error) { + $('#map').hide(); + $('#console').text(unableToDetermineText).show(); + switch(error.code) { + case error.PERMISSION_DENIED: + setLatLon('E-1','E-1'); + break; + case error.POSITION_UNAVAILABLE: + setLatLon('E-2','E-2'); + break; + case error.TIMEOUT: + setLatLon('E-3','E-3'); + break; + case error.UNKNOWN_ERROR: + setLatLon('E-4','E-4'); + break; + } + }); + } else { + $('#map').hide(); + $('#console').text(unableToDetermineText).show(); + setLatLon('E-5','E-5'); + } +} + +function setLatLon(lat, lon) { + $('#latitude').val(lat); + $('#longitude').val(lon); +} + +var marker; +var map; +function resetLatLon(lat, lon) { + map.setView([lat, lon], 15); + marker.setLatLng(L.latLng(lat, lon)); +} + +function closeAndReset(lat, lon) { + $('#save-group').hide(); + $('#close-button').show(); + $('#friendly-location').show(); + $('#save-for-address').hide(); + resetLatLon(lat, lon); +} + +function initializeMapForCustomer(latitude, longitude, yourLocationText) { + map = L.map('map').setView([latitude, longitude], 15); + L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { + attribution: '© OpenStreetMap contributors' + }).addTo(map); + marker = L.marker([latitude, longitude], {draggable: true}) + .addTo(map) + .bindPopup(yourLocationText); + + marker.on('dragend', function(event) { + setLatLon(event.target.getLatLng().lat, event.target.getLatLng().lng); + }); +} + +function initializeMapForStaff(latitude, longitude, usersLocationText) { + map = L.map('map').setView([latitude, longitude], 15); + L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { + attribution: '© OpenStreetMap contributors' + }).addTo(map); + marker = L.marker([latitude, longitude], {draggable: true}) + .addTo(map) + .bindPopup(usersLocationText); + + marker.on('dragend', function(event) { + setLatLon(event.target.getLatLng().lat, event.target.getLatLng().lng); + $('#save-group').show(); + $('#close-button').hide(); + $('#friendly-location').hide(); + $('#save-for-address').show(); + }); + + $('#map-modal').on('shown.bs.modal', function(){ + setTimeout(function() { + map.invalidateSize(); + }, 10); + }); +} + +function getFriendlyLocation(latitude, longitude) { + var URL = 'http://nominatim.openstreetmap.org/reverse?format=json&lat='+ latitude +'&lon='+ longitude +'&zoom=15&addressdetails=1'; + $.getJSON(URL, function(data) { + $('#friendly-location').text(data.display_name); + }); +} + jQuery(document).ready(loadJquery); diff --git a/language/en/text.php b/language/en/text.php index 460a94f5..10a2aee3 100644 --- a/language/en/text.php +++ b/language/en/text.php @@ -44,6 +44,28 @@ $hesklang['show_number_merged_help'] = 'If enabled, the user will be able to see $hesklang['latest_top_on_home'] = 'Latest/Top articles on home page'; $hesklang['latest_top_on_home_help'] = 'Select YES to display the top and latest knowledgebase articles on the home page. Otherwise, a link to the knowledgebase will appear on the home page.'; +$hesklang['location_unavailable'] = "Location unavailable. Click for more information."; +$hesklang['click_for_map'] = "View map of user's location"; +$hesklang['request_user_location'] = "Request Location"; +$hesklang['request_user_location_help'] = "If enabled, the help desk will ask for the customer's location, allowing staff to + see a map of the customer's location when they created the ticket."; +$hesklang['users_location'] = "User's Location"; +$hesklang['location_unavailable_0'] = "User's location is not available because the ticket was created before location tracking was enabled."; +$hesklang['location_unavailable_1'] = "User's location is not available because the user refused to share it."; +$hesklang['location_unavailable_2'] = "User's location is not available because the help desk was unable to determine the user's position."; +$hesklang['location_unavailable_3'] = "User's location is not available because the help desk was not able to determine the user's position in + a reasonable amount of time."; +$hesklang['location_unavailable_4'] = "An unknown error occurred when trying to obtain the user's location."; +$hesklang['location_unavailable_5'] = "User's location is not available because the user's browser did not meet the minimum +requirements for tracking their location when the ticket was submitted."; +$hesklang['save_location'] = 'Save Location'; +$hesklang['close_modal_without_saving'] = 'Close without saving'; +$hesklang['ticket_location_updated'] = 'Ticket location has been updated!'; +$hesklang['location_colon'] = 'Location:'; +$hesklang['your_current_location'] = 'Your location'; +$hesklang['requesting_location_ellipsis'] = 'Requesting location...'; +$hesklang['unable_to_determine_location'] = 'Unable to determine your location, or you declined to share it.'; +$hesklang['save_to_see_updated_address'] = 'Save the new location to see the updated address'; // ADDED OR MODIFIED IN Mods for HESK 2.2.1 $hesklang['popart_no_colon']='Top Knowledgebase Articles'; // same as $hesklang['popart'] but without a colon (:) diff --git a/modsForHesk_settings.inc.php b/modsForHesk_settings.inc.php index 8471bd0b..3406ac42 100644 --- a/modsForHesk_settings.inc.php +++ b/modsForHesk_settings.inc.php @@ -43,4 +43,7 @@ $modsForHesk_settings['new_kb_article_visibility'] = 0; $modsForHesk_settings['attachments'] = 0; //-- Setting for showing number of merged tickets in the ticket search screen. 0 = Disable, 1 = Enable -$modsForHesk_settings['show_number_merged'] = 1; \ No newline at end of file +$modsForHesk_settings['show_number_merged'] = 1; + +//-- Setting for requesting user's location. 0 = Disable, 1 = Enable +$modsForHesk_settings['request_location'] = 0; \ No newline at end of file diff --git a/submit_ticket.php b/submit_ticket.php index eea8f368..44e6774f 100644 --- a/submit_ticket.php +++ b/submit_ticket.php @@ -427,6 +427,10 @@ if ($hesk_settings['attachments']['use'] && ! empty($attachments) ) } } +// Set latitude and longitude +$tmpvar['latitude'] = hesk_POST('latitude'); +$tmpvar['longitude'] = hesk_POST('longitude'); + // Should the helpdesk validate emails? $createTicket = true; if ($modsForHesk_settings['customer_email_verification_required'])