WP Store Locator - Version 1.2.20

Version Description

  • Fixed the directions url sometimes showing an incomplete address due to an encoding issue
  • Fixed the 'items' count on the store overview page showing the incorrect number after deleting a store
  • Fixed the autocomplete for the 'start point' field sometimes not working on the settings page
  • Fixed php notices breaking the store search when wp_debug is set to true
  • Fixed the bulk actions when set to 'Bulk Actions' showing the full store list without paging
  • Fixed small css alignment issues in the admin area
  • Fixed the js script still trying to load store data when autoload was disabled
  • Fixed the clickable area around the marker being to big
  • Improved: After a user clicks on 'directions' and then clicks 'back', the map view is returned to the original location
  • Removed: the 'Preview location on the map' button no longer updates the zip code value it receives from the Google Maps API
  • Changed the way the dropdown filters are handled on mobile devices. They are now styled and behave according to the default UI of the device
  • Added support for WP Multisite
  • Added 'Screen Options' for the 'Current Stores' page, so you can define the amount of stores that are visible on a single page
  • Added the option to make phone numbers clickable on mobile devices by adding a link around them with 'tel:'
  • Added the option to make store names automatically clickable if the store url exists
  • Added the option to show a 'zoom here' and 'street view' (when available) into the infowindow
  • Added a second address field to the store fields
  • Added the option to enable marker clusters
  • Added the option to set a default country for the "Add Store" page
  • Added Dutch (nl_NL) translations
  • Added a .pot file to the languages folder for translators
  • Added error handling for the driving directions
  • Added several filters for developers: 'wpsl_templates' for loading a custom template from another directory 'wpsl_menu_position' for adjusting the position of the store locator menu in the admin panel 'wpsl_capability' to manually set the required user capability for adding/editing stores 'wpsl_gmap_api_attributes' to modify the Google maps parameters ( change the map language dynamically )
Download this release

Release Info

Developer tijmensmit
Plugin Icon 128x128 WP Store Locator
Version 1.2.20
Comparing to
See all releases

Code changes from version 1.2.13 to 1.2.20

admin/class-admin.php CHANGED
@@ -62,7 +62,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
62
  add_action( 'admin_footer', array( $this, 'show_location_warning' ) );
63
  }
64
  }
65
-
66
  register_setting( 'wpsl_settings', 'wpsl_settings', array( $this, 'sanitize_settings' ) );
67
  }
68
 
@@ -125,7 +125,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
125
 
126
  /* Add the default value for the 'more info' label */
127
  if ( empty( $this->settings['more_label'] ) ) {
128
- $this->settings['more_label'] = 'More info';
129
  }
130
 
131
  /* Add the default value mouse focus option */
@@ -137,31 +137,95 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
137
  }
138
  }
139
 
140
- if ( version_compare( $current_version, '1.2.12', '<' ) ) {
141
  if ( is_array( $this->settings ) ) {
142
  /* Add the default value for the 'more info link' link option */
143
  if ( empty( $this->settings['more_info_location'] ) ) {
144
- $this->settings['more_info_location'] = 'info window';
145
  }
146
-
147
  /* Add the default value for the back label */
148
  if ( empty( $this->settings['back_label'] ) ) {
149
- $this->settings['back_label'] = 'Back';
150
  }
151
-
152
  /* Add the default value for the reset label */
153
  if ( empty( $this->settings['reset_label'] ) ) {
154
- $this->settings['reset_label'] = 'Reset';
155
  }
156
-
157
  /* Add the default value for removing the scroll bar when the store listing is shown below the map */
158
  if ( empty( $this->settings['store_below_scroll'] ) ) {
159
- $this->settings['store_below_scroll'] = '0';
160
  }
161
 
162
  update_option( 'wpsl_settings', $this->settings );
163
  }
164
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
  update_option( 'wpsl_version', WPSL_VERSION_NUM );
167
  }
@@ -184,12 +248,33 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
184
  * @return void
185
  */
186
  public function create_admin_menu() {
187
- add_menu_page( 'Store Locator', __( 'Store Locator', 'wpsl' ), __( 'manage_options', 'wpsl' ), 'wpsl_store_editor', array( $this, 'manage_stores' ), plugins_url( 'img/store-locator-icon.png', dirname( __FILE__ ) ) );
188
- add_submenu_page( 'wpsl_store_editor', __( 'Manage Stores', 'wpsl' ), __( 'Manage Stores', 'wpsl' ), 'manage_options', 'wpsl_store_editor', array( $this, 'manage_stores' ) );
189
- add_submenu_page( 'wpsl_store_editor', __( 'Add Store', 'wpsl' ), __( 'Add Store', 'wpsl' ), 'manage_options', 'wpsl_add_store', array( $this, 'add_store' ) );
190
  add_submenu_page( 'wpsl_store_editor', __( 'Settings', 'wpsl' ), __( 'Settings', 'wpsl' ), 'manage_options', 'wpsl_settings', array( $this, 'show_settings' ) );
191
- add_submenu_page( 'wpsl_store_editor', __( 'FAQ', 'wpsl' ), __( 'FAQ', 'wpsl' ), 'manage_options', 'wpsl_faq', array( $this, 'show_faq' ) );
192
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
  /**
195
  * Load the add store template
@@ -226,8 +311,10 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
226
 
227
  $this->store_actions();
228
 
 
 
229
  /* Check which store template to show */
230
- switch ( $_GET['action'] ) {
231
  case 'edit_store':
232
  require_once( WPSL_PLUGIN_DIR . 'admin/templates/edit-store.php' );
233
  break;
@@ -246,8 +333,8 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
246
  public function handle_store_data() {
247
 
248
  global $wpdb;
249
-
250
- if ( !current_user_can( 'manage_options' ) )
251
  die( '-1' );
252
 
253
  check_admin_referer( 'wpsl_' . $_POST['wpsl_actions'] );
@@ -267,12 +354,17 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
267
  $this->store_data['country-iso'] = $_POST['wpsl']['country-iso'];
268
  $this->store_data['latlng'] = $latlng;
269
  }
270
-
271
- if ( $_POST['wpsl_actions'] == 'add_new_store' )
272
- $this->add_new_store();
273
-
274
- if ( $_POST['wpsl_actions'] == 'update_store' )
275
- $this->update_store();
 
 
 
 
 
276
  }
277
  }
278
 
@@ -290,7 +382,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
290
 
291
  $store_id = absint( $_POST['store_id'] );
292
 
293
- if ( !current_user_can( 'manage_options' ) )
294
  die( '-1' );
295
 
296
  check_ajax_referer( 'wpsl_delete_nonce_'.$store_id );
@@ -319,10 +411,11 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
319
  $wpdb->prepare(
320
  "
321
  UPDATE $wpdb->wpsl_stores
322
- SET store = %s, street = %s, city = %s, state = %s, zip = %s, country = %s, country_iso = %s, lat = %s, lng = %s, description = %s, phone = %s, fax = %s, url = %s, email = %s, hours = %s, thumb_id = %d, active = %d
323
  WHERE wpsl_id = %d",
324
  $this->store_data['store'],
325
- $this->store_data['street'],
 
326
  $this->store_data['city'],
327
  $this->store_data['state'],
328
  strtoupper( $this->store_data['zip'] ),
@@ -369,11 +462,12 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
369
  $wpdb->prepare(
370
  "
371
  INSERT INTO $wpdb->wpsl_stores
372
- (store, street, city, state, zip, country, country_iso, lat, lng, description, phone, fax, url, email, hours, thumb_id)
373
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d)
374
  ",
375
  $this->store_data['store'],
376
- $this->store_data['street'],
 
377
  $this->store_data['city'],
378
  $this->store_data['state'],
379
  strtoupper ( $this->store_data['zip'] ),
@@ -411,7 +505,10 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
411
  * @return string the default setting value
412
  */
413
  public function get_default_setting( $setting ) {
414
- return $this->default_settings[$setting];
 
 
 
415
  }
416
 
417
  /**
@@ -424,7 +521,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
424
 
425
  $store_data = $_POST['wpsl'];
426
 
427
- if ( empty( $store_data['store'] ) || ( empty( $store_data['street'] ) ) || ( empty( $store_data['city'] ) ) || ( empty( $store_data['zip'] ) ) || ( empty( $store_data['country'] ) ) ) {
428
  add_settings_error ( 'validate-store', esc_attr( 'validate-store' ), __( 'Please fill in all the required fields.', 'wpsl' ), 'error' );
429
  } else {
430
  return $store_data;
@@ -454,6 +551,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
454
  * @return void
455
  */
456
  public function show_settings() {
 
457
  require 'templates/map-settings.php';
458
  }
459
 
@@ -467,6 +565,41 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
467
  require 'templates/faq.php';
468
  }
469
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
470
  /**
471
  * Handle the different validation errors for the plugin settings
472
  *
@@ -516,7 +649,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
516
 
517
  global $current_user;
518
 
519
- if ( !current_user_can( 'manage_options' ) )
520
  die( '-1' );
521
  check_ajax_referer( 'wpsl-dismiss' );
522
 
@@ -532,24 +665,11 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
532
  * @return array $output The setting values
533
  */
534
  public function sanitize_settings() {
535
- $map_types = array(
536
- 'roadmap',
537
- 'satellite',
538
- 'hybrid',
539
- 'terrain'
540
- );
541
- $unit_values = array(
542
- 'px',
543
- '%'
544
- );
545
- $distance_units = array(
546
- 'km',
547
- 'mi'
548
- );
549
- $more_info_locations = array(
550
- 'store listings',
551
- 'info window'
552
- );
553
 
554
  $output['api_key'] = sanitize_text_field( $_POST['wpsl_api']['key'] );
555
  $output['api_language'] = wp_filter_nohtml_kses( $_POST['wpsl_api']['language'] );
@@ -609,6 +729,21 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
609
  $output['pan_controls'] = isset( $_POST['wpsl_map']['pan_controls'] ) ? 1 : 0;
610
  $output['control_position'] = ( $_POST['wpsl_map']['control_position'] == 'left' ) ? 'left' : 'right';
611
  $output['control_style'] = ( $_POST['wpsl_map']['control_style'] == 'small' ) ? 'small' : 'large';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
612
 
613
  /* Check the height value of the map */
614
  if ( absint( $_POST['wpsl_design']['height_value'] ) ) {
@@ -637,14 +772,24 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
637
  } else {
638
  $output['label_width'] = $this->get_default_setting( 'label_width' );
639
  }
 
 
 
 
 
 
 
640
 
641
  $output['results_dropdown'] = isset( $_POST['wpsl_design']['design_results'] ) ? 1 : 0;
642
  $output['new_window'] = isset( $_POST['wpsl_design']['new_window'] ) ? 1 : 0;
643
  $output['reset_map'] = isset( $_POST['wpsl_design']['reset_map'] ) ? 1 : 0;
644
- $output['store_below'] = isset( $_POST['wpsl_design']['store_below'] ) ? 1 : 0;
645
  $output['store_below_scroll'] = isset( $_POST['wpsl_design']['store_below_scroll'] ) ? 1 : 0;
646
  $output['direction_redirect'] = isset( $_POST['wpsl_design']['direction_redirect'] ) ? 1 : 0;
647
  $output['more_info'] = isset( $_POST['wpsl_design']['more_info'] ) ? 1 : 0;
 
 
 
 
648
 
649
  /* Check if we have a valid 'more info' location */
650
  if ( in_array( $_POST['wpsl_design']['more_info_location'], $more_info_locations ) ) {
@@ -653,10 +798,11 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
653
  $output['more_info_location'] = $this->get_default_setting( 'more_info_location' );
654
  }
655
 
656
- $output['mouse_focus'] = isset( $_POST['wpsl_design']['mouse_focus'] ) ? 1 : 0;
657
- $output['start_marker'] = wp_filter_nohtml_kses( $_POST['wpsl_map']['start_marker'] );
658
- $output['store_marker'] = wp_filter_nohtml_kses( $_POST['wpsl_map']['store_marker'] );
659
-
 
660
  $missing_labels = false;
661
  $required_labels = array(
662
  'search',
@@ -667,8 +813,11 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
667
  'results',
668
  'more',
669
  'directions',
 
670
  'back',
671
  'reset',
 
 
672
  'error',
673
  'phone',
674
  'fax',
@@ -741,11 +890,11 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
741
  $msg = __( 'The Google Geocoding API returned no results for the store location. Please change the location and try again.', 'wpsl' );
742
  break;
743
  case 'OVER_QUERY_LIMIT':
744
- $msg = __( 'You have reached the daily allowed geocoding limit, you can read more <a href="https://developers.google.com/maps/documentation/geocoding/#Limits">here</a>.', 'wpsl' );
745
  break;
746
  default:
747
  $msg = __( 'The Google Geocoding API failed to return valid data, please try again later.', 'wpsl' );
748
- break;
749
  }
750
 
751
  if ( !empty( $msg ) ) {
@@ -761,7 +910,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
761
  */
762
  public function get_latlng() {
763
 
764
- $address = $this->store_data["street"].','.$this->store_data["city"].','.$this->store_data["zip"].','.$this->store_data["country"];
765
  $url = "http://maps.googleapis.com/maps/api/geocode/json?address=".urlencode( $address )."&sensor=false&language=".$this->settings['api_language'];
766
 
767
  if ( extension_loaded( "curl" ) && function_exists( "curl_init" ) ) {
@@ -790,15 +939,15 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
790
  */
791
  public function filter_country_name( $response ) {
792
 
793
- $length = count( $response[results][0][address_components] );
794
 
795
  /* Loop over the address components untill we find the country,political part */
796
  for ( $i = 0; $i < $length; $i++ ) {
797
- $address_component = $response[results][0][address_components][$i][types];
798
 
799
  if ( $address_component[0] == 'country' && $address_component[1] == 'political' ) {
800
- $country_name['long_name'] = $response[results][0][address_components][$i][long_name];
801
- $country_name['short_name'] = $response[results][0][address_components][$i][short_name];
802
 
803
  break;
804
  }
@@ -904,6 +1053,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
904
  * and set the active value to selected.
905
  *
906
  * @since 1.0
 
907
  * @return string $dropdown The html for the distance option list
908
  */
909
  public function show_distance_units() {
@@ -923,11 +1073,109 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
923
 
924
  return $dropdown;
925
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
926
 
927
  /**
928
  * Create a dropdown where users can select the used map type
929
  *
930
  * @since 1.0
 
931
  * @return string $dropdown The html for the map option list
932
  */
933
  public function show_map_types() {
@@ -989,13 +1237,14 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
989
  * Create a dropdown where users can select location where the 'more info' data is shown
990
  *
991
  * @since 1.2.12
 
992
  * @return string $dropdown The html for the more info options list
993
  */
994
  public function show_more_info_options() {
995
 
996
  $items = array(
997
- 'store listings' => 'In the store listings',
998
- 'info window' => 'In the info window on the map'
999
  );
1000
  $dropdown = '<select id="wpsl-more-info-list" name="wpsl_design[more_info_location]">';
1001
 
@@ -1080,7 +1329,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
1080
  break;
1081
  case 'region':
1082
  $api_option_list = array (
1083
- __('Select your region', '') => '',
1084
  __('Afghanistan', 'wpsl') => 'af',
1085
  __('Albania', 'wpsl') => 'al',
1086
  __('Algeria', 'wpsl') => 'dz',
@@ -1292,6 +1541,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
1292
 
1293
  /* Make sure we have a array with a value */
1294
  if ( !empty( $api_option_list ) && ( is_array( $api_option_list ) ) ) {
 
1295
  $i = 0;
1296
 
1297
  foreach ( $api_option_list as $api_option_key => $api_option_value ) {
@@ -1303,7 +1553,7 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
1303
  $selected = ( $this->settings['api_'.$list] == $api_option_value ) ? 'selected="selected"' : '';
1304
  }
1305
 
1306
- $option_list .= '<option value="' . esc_attr( $api_option_value ) . '"' . $selected . '> ' . esc_html( $api_option_key ) . '</option>';
1307
  $i++;
1308
  }
1309
 
@@ -1328,6 +1578,44 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
1328
  }
1329
  }
1330
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1331
  /**
1332
  * Add the required admin script
1333
  *
@@ -1340,10 +1628,13 @@ if ( !class_exists( 'WPSL_Admin' ) ) {
1340
  wp_enqueue_style( 'jquery-style', '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css' );
1341
  wp_enqueue_style( 'wpsl-admin-css', plugins_url( '/css/style.css', __FILE__ ), false );
1342
  $this->check_icon_font_usage();
1343
- wp_enqueue_script( 'wpsl-gmap', ( "//maps.google.com/maps/api/js?sensor=false&libraries=places&language=" . $this->settings['api_language'] ), false ); // we set the language here to make sure the geocode response returns the country name in the correct language
1344
  wp_enqueue_script( 'wpsl-admin-js', plugins_url( '/js/wpsl-admin.js', __FILE__ ), array( 'jquery' ), false );
1345
  wp_enqueue_script( 'wpsl-queue', plugins_url( '/js/ajax-queue.js', __FILE__ ), array( 'jquery' ), false );
1346
  wp_enqueue_script( 'wpsl-retina', plugins_url( '/js/retina-1.1.0.js', __FILE__ ), array( 'jquery' ), false );
 
 
 
1347
  }
1348
  }
1349
 
62
  add_action( 'admin_footer', array( $this, 'show_location_warning' ) );
63
  }
64
  }
65
+
66
  register_setting( 'wpsl_settings', 'wpsl_settings', array( $this, 'sanitize_settings' ) );
67
  }
68
 
125
 
126
  /* Add the default value for the 'more info' label */
127
  if ( empty( $this->settings['more_label'] ) ) {
128
+ $this->settings['more_label'] = __( 'More info', 'wpsl' );
129
  }
130
 
131
  /* Add the default value mouse focus option */
137
  }
138
  }
139
 
140
+ if ( version_compare( $current_version, '1.2.12', '<' ) ) {
141
  if ( is_array( $this->settings ) ) {
142
  /* Add the default value for the 'more info link' link option */
143
  if ( empty( $this->settings['more_info_location'] ) ) {
144
+ $this->settings['more_info_location'] = __( 'info window', 'wpsl' );
145
  }
146
+
147
  /* Add the default value for the back label */
148
  if ( empty( $this->settings['back_label'] ) ) {
149
+ $this->settings['back_label'] = __( 'Back', 'wpsl' );
150
  }
151
+
152
  /* Add the default value for the reset label */
153
  if ( empty( $this->settings['reset_label'] ) ) {
154
+ $this->settings['reset_label'] = __( 'Reset', 'wpsl' );
155
  }
156
+
157
  /* Add the default value for removing the scroll bar when the store listing is shown below the map */
158
  if ( empty( $this->settings['store_below_scroll'] ) ) {
159
+ $this->settings['store_below_scroll'] = 0;
160
  }
161
 
162
  update_option( 'wpsl_settings', $this->settings );
163
  }
164
+ }
165
+
166
+ if ( version_compare( $current_version, '1.2.20', '<' ) ) {
167
+
168
+ global $wpdb;
169
+
170
+ /* Rename the street field to address */
171
+ $wpdb->query( "ALTER TABLE $wpdb->wpsl_stores CHANGE street address VARCHAR(255)" );
172
+
173
+ /* Add the second address field */
174
+ $wpdb->query( "ALTER TABLE $wpdb->wpsl_stores ADD address2 VARCHAR(255) NULL AFTER address" );
175
+
176
+ if ( is_array( $this->settings ) ) {
177
+ if ( empty( $this->settings['store_url'] ) ) {
178
+ $this->settings['store_url'] = 0;
179
+ }
180
+
181
+ if ( empty( $this->settings['phone_url'] ) ) {
182
+ $this->settings['phone_url'] = 0;
183
+ }
184
+
185
+ if ( empty( $this->settings['marker_clusters'] ) ) {
186
+ $this->settings['marker_clusters'] = 0;
187
+ }
188
+
189
+ if ( empty( $this->settings['cluster_zoom'] ) ) {
190
+ $this->settings['cluster_zoom'] = 0;
191
+ }
192
+
193
+ if ( empty( $this->settings['cluster_size'] ) ) {
194
+ $this->settings['cluster_size'] = 0;
195
+ }
196
+
197
+ if ( empty( $this->settings['template_id'] ) ) {
198
+ $this->settings['template_id'] = ( $this->settings['store_below'] ) ? 1 : 0;
199
+ unset( $this->settings['store_below'] );
200
+ }
201
+
202
+ if ( empty( $this->settings['marker_streetview'] ) ) {
203
+ $this->settings['marker_streetview'] = 0;
204
+ }
205
+
206
+ if ( empty( $this->settings['marker_zoom_to'] ) ) {
207
+ $this->settings['marker_zoom_to'] = 0;
208
+ }
209
+
210
+ if ( !isset( $this->settings['editor_country'] ) ) {
211
+ $this->settings['editor_country'] = '';
212
+ }
213
+
214
+ if ( empty( $this->settings['street_view_label'] ) ) {
215
+ $this->settings['street_view_label'] = __( 'Street view', 'wpsl' );
216
+ }
217
+
218
+ if ( empty( $this->settings['zoom_here_label'] ) ) {
219
+ $this->settings['zoom_here_label'] = __( 'Zoom here', 'wpsl' );
220
+ }
221
+
222
+ if ( empty( $this->settings['no_directions_label'] ) ) {
223
+ $this->settings['no_directions_label'] = __( 'No route could be found between the origin and destination', 'wpsl' );
224
+ }
225
+
226
+ update_option( 'wpsl_settings', $this->settings );
227
+ }
228
+ }
229
 
230
  update_option( 'wpsl_version', WPSL_VERSION_NUM );
231
  }
248
  * @return void
249
  */
250
  public function create_admin_menu() {
251
+ $hook = add_menu_page( 'Store Locator', __( 'Store Locator', 'wpsl' ), apply_filters( 'wpsl_capability', 'manage_options' ), 'wpsl_store_editor', array( $this, 'manage_stores' ), plugins_url( 'img/store-locator-icon.png', dirname( __FILE__ ) ), apply_filters( 'wpsl_menu_position', null ) );
252
+ add_submenu_page( 'wpsl_store_editor', __( 'Manage Stores', 'wpsl' ), __( 'Manage Stores', 'wpsl' ), apply_filters( 'wpsl_capability', 'manage_options' ), 'wpsl_store_editor', array( $this, 'manage_stores' ) );
253
+ add_submenu_page( 'wpsl_store_editor', __( 'Add Store', 'wpsl' ), __( 'Add Store', 'wpsl' ), apply_filters( 'wpsl_capability', 'manage_options' ), 'wpsl_add_store', array( $this, 'add_store' ) );
254
  add_submenu_page( 'wpsl_store_editor', __( 'Settings', 'wpsl' ), __( 'Settings', 'wpsl' ), 'manage_options', 'wpsl_settings', array( $this, 'show_settings' ) );
255
+ add_submenu_page( 'wpsl_store_editor', __( 'FAQ', 'wpsl' ), __( 'FAQ', 'wpsl' ), apply_filters( 'wpsl_capability', 'manage_options' ), 'wpsl_faq', array( $this, 'show_faq' ) );
256
+
257
+ add_action( "load-$hook", array( $this, 'add_screen_options' ) );
258
+ }
259
+
260
+ /**
261
+ * Add the screen options to the store overview page
262
+ *
263
+ * Users can define the amount of visible stores
264
+ *
265
+ * @since 1.2.20
266
+ * @return void
267
+ */
268
+ function add_screen_options() {
269
+ $option = 'per_page';
270
+ $args = array(
271
+ 'label' => __( 'Stores', 'wpsl' ),
272
+ 'default' => 20,
273
+ 'option' => 'wpsl_stores_per_page'
274
+ );
275
+
276
+ add_screen_option( $option, $args );
277
+ }
278
 
279
  /**
280
  * Load the add store template
311
 
312
  $this->store_actions();
313
 
314
+ $actions = ( isset( $_GET['action'] ) ) ? $_GET['action'] : '';
315
+
316
  /* Check which store template to show */
317
+ switch ( $actions ) {
318
  case 'edit_store':
319
  require_once( WPSL_PLUGIN_DIR . 'admin/templates/edit-store.php' );
320
  break;
333
  public function handle_store_data() {
334
 
335
  global $wpdb;
336
+
337
+ if ( !current_user_can( apply_filters( 'wpsl_capability', 'manage_options' ) ) )
338
  die( '-1' );
339
 
340
  check_admin_referer( 'wpsl_' . $_POST['wpsl_actions'] );
354
  $this->store_data['country-iso'] = $_POST['wpsl']['country-iso'];
355
  $this->store_data['latlng'] = $latlng;
356
  }
357
+
358
+ $store_action = ( isset( $_POST['wpsl_actions'] ) ) ? $_POST['wpsl_actions'] : '';
359
+
360
+ switch ( $store_action ) {
361
+ case 'add_new_store':
362
+ $this->add_new_store();
363
+ break;
364
+ case 'update_store':
365
+ $this->update_store();
366
+ break;
367
+ };
368
  }
369
  }
370
 
382
 
383
  $store_id = absint( $_POST['store_id'] );
384
 
385
+ if ( !current_user_can( apply_filters( 'wpsl_capability', 'manage_options' ) ) )
386
  die( '-1' );
387
 
388
  check_ajax_referer( 'wpsl_delete_nonce_'.$store_id );
411
  $wpdb->prepare(
412
  "
413
  UPDATE $wpdb->wpsl_stores
414
+ SET store = %s, address = %s, address2 = %s, city = %s, state = %s, zip = %s, country = %s, country_iso = %s, lat = %s, lng = %s, description = %s, phone = %s, fax = %s, url = %s, email = %s, hours = %s, thumb_id = %d, active = %d
415
  WHERE wpsl_id = %d",
416
  $this->store_data['store'],
417
+ $this->store_data['address'],
418
+ $this->store_data['address2'],
419
  $this->store_data['city'],
420
  $this->store_data['state'],
421
  strtoupper( $this->store_data['zip'] ),
462
  $wpdb->prepare(
463
  "
464
  INSERT INTO $wpdb->wpsl_stores
465
+ (store, address, address2, city, state, zip, country, country_iso, lat, lng, description, phone, fax, url, email, hours, thumb_id)
466
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d)
467
  ",
468
  $this->store_data['store'],
469
+ $this->store_data['address'],
470
+ $this->store_data['address2'],
471
  $this->store_data['city'],
472
  $this->store_data['state'],
473
  strtoupper ( $this->store_data['zip'] ),
505
  * @return string the default setting value
506
  */
507
  public function get_default_setting( $setting ) {
508
+
509
+ global $wpsl;
510
+
511
+ return $wpsl->default_settings[$setting];
512
  }
513
 
514
  /**
521
 
522
  $store_data = $_POST['wpsl'];
523
 
524
+ if ( empty( $store_data['store'] ) || ( empty( $store_data['address'] ) ) || ( empty( $store_data['city'] ) ) || ( empty( $store_data['zip'] ) ) || ( empty( $store_data['country'] ) ) ) {
525
  add_settings_error ( 'validate-store', esc_attr( 'validate-store' ), __( 'Please fill in all the required fields.', 'wpsl' ), 'error' );
526
  } else {
527
  return $store_data;
551
  * @return void
552
  */
553
  public function show_settings() {
554
+ $this->deregister_other_gmaps();
555
  require 'templates/map-settings.php';
556
  }
557
 
565
  require 'templates/faq.php';
566
  }
567
 
568
+ /**
569
+ * Create the nav menu shown on store locator pages
570
+ *
571
+ * @since 1.2.20
572
+ * @return string $menu_nav The content of the menu
573
+ */
574
+ public function create_menu() {
575
+
576
+ $menu_items = array(
577
+ 'wpsl_store_editor' => __( 'Current Stores', 'wpsl' ),
578
+ 'wpsl_add_store' => __( 'Add Store', 'wpsl' ),
579
+ 'wpsl_settings' => __( 'Settings', 'wpsl' )
580
+ );
581
+
582
+ $menu_nav = '<ul id="wpsl-mainnav" class="nav-tab-wrapper">';
583
+
584
+ foreach ( $menu_items as $index => $item ) {
585
+ if ( ( array_key_exists( $_GET['page'], $menu_items ) ) && ( $_GET['page'] == $index ) ) {
586
+ $active_tab = 'nav-tab-active';
587
+ } else {
588
+ $active_tab = '';
589
+ }
590
+
591
+ /* Make sure the settings page isn't added to the menu if the user can't 'manage_options' */
592
+ if ( ( $index == 'wpsl_settings' ) && ( !current_user_can( 'manage_options' ) ) )
593
+ break;
594
+
595
+ $menu_nav .= '<li><a class="nav-tab ' . $active_tab . '" href="'. admin_url( 'admin.php?page=' . $index . '' ) .'">'. $item .'</a></li>';
596
+ }
597
+
598
+ $menu_nav .= '</ul>';
599
+
600
+ return $menu_nav;
601
+ }
602
+
603
  /**
604
  * Handle the different validation errors for the plugin settings
605
  *
649
 
650
  global $current_user;
651
 
652
+ if ( !current_user_can( apply_filters( 'wpsl_capability', 'manage_options' ) ) )
653
  die( '-1' );
654
  check_ajax_referer( 'wpsl-dismiss' );
655
 
665
  * @return array $output The setting values
666
  */
667
  public function sanitize_settings() {
668
+
669
+ $map_types = array( 'roadmap', 'satellite', 'hybrid', 'terrain' );
670
+ $unit_values = array( 'px', '%' );
671
+ $distance_units = array( 'km', 'mi' );
672
+ $more_info_locations = array( 'store listings', 'info window' );
 
 
 
 
 
 
 
 
 
 
 
 
 
673
 
674
  $output['api_key'] = sanitize_text_field( $_POST['wpsl_api']['key'] );
675
  $output['api_language'] = wp_filter_nohtml_kses( $_POST['wpsl_api']['language'] );
729
  $output['pan_controls'] = isset( $_POST['wpsl_map']['pan_controls'] ) ? 1 : 0;
730
  $output['control_position'] = ( $_POST['wpsl_map']['control_position'] == 'left' ) ? 'left' : 'right';
731
  $output['control_style'] = ( $_POST['wpsl_map']['control_style'] == 'small' ) ? 'small' : 'large';
732
+ $output['marker_clusters'] = isset( $_POST['wpsl_map']['marker_clusters'] ) ? 1 : 0;
733
+
734
+ /* Check for a valid cluster zoom value */
735
+ if ( in_array( $_POST['wpsl_map']['cluster_zoom'], $this->get_default_cluster_option( 'cluster_zoom' ) ) ) {
736
+ $output['cluster_zoom'] = $_POST['wpsl_map']['cluster_zoom'];
737
+ } else {
738
+ $output['cluster_zoom'] = $this->get_default_setting( 'cluster_zoom' );
739
+ }
740
+
741
+ /* Check for a valid cluster size value */
742
+ if ( in_array( $_POST['wpsl_map']['cluster_size'], $this->get_default_cluster_option( 'cluster_size' ) ) ) {
743
+ $output['cluster_size'] = $_POST['wpsl_map']['cluster_size'];
744
+ } else {
745
+ $output['cluster_size'] = $this->get_default_setting( 'cluster_size' );
746
+ }
747
 
748
  /* Check the height value of the map */
749
  if ( absint( $_POST['wpsl_design']['height_value'] ) ) {
772
  } else {
773
  $output['label_width'] = $this->get_default_setting( 'label_width' );
774
  }
775
+
776
+ /* Make sure we have a valid template ID */
777
+ if ( absint( $_POST['wpsl_design']['template'] ) ) {
778
+ $output['template_id'] = $_POST['wpsl_design']['template'];
779
+ } else {
780
+ $output['template_id'] = $this->get_default_setting( 'template_id' );
781
+ }
782
 
783
  $output['results_dropdown'] = isset( $_POST['wpsl_design']['design_results'] ) ? 1 : 0;
784
  $output['new_window'] = isset( $_POST['wpsl_design']['new_window'] ) ? 1 : 0;
785
  $output['reset_map'] = isset( $_POST['wpsl_design']['reset_map'] ) ? 1 : 0;
 
786
  $output['store_below_scroll'] = isset( $_POST['wpsl_design']['store_below_scroll'] ) ? 1 : 0;
787
  $output['direction_redirect'] = isset( $_POST['wpsl_design']['direction_redirect'] ) ? 1 : 0;
788
  $output['more_info'] = isset( $_POST['wpsl_design']['more_info'] ) ? 1 : 0;
789
+ $output['store_url'] = isset( $_POST['wpsl_design']['store_url'] ) ? 1 : 0;
790
+ $output['phone_url'] = isset( $_POST['wpsl_design']['phone_url'] ) ? 1 : 0;
791
+ $output['marker_streetview'] = isset( $_POST['wpsl_design']['marker_streetview'] ) ? 1 : 0;
792
+ $output['marker_zoom_to'] = isset( $_POST['wpsl_design']['marker_zoom_to'] ) ? 1 : 0;
793
 
794
  /* Check if we have a valid 'more info' location */
795
  if ( in_array( $_POST['wpsl_design']['more_info_location'], $more_info_locations ) ) {
798
  $output['more_info_location'] = $this->get_default_setting( 'more_info_location' );
799
  }
800
 
801
+ $output['mouse_focus'] = isset( $_POST['wpsl_design']['mouse_focus'] ) ? 1 : 0;
802
+ $output['start_marker'] = wp_filter_nohtml_kses( $_POST['wpsl_map']['start_marker'] );
803
+ $output['store_marker'] = wp_filter_nohtml_kses( $_POST['wpsl_map']['store_marker'] );
804
+ $output['editor_country'] = sanitize_text_field( $_POST['wpsl_editor']['default_country'] );
805
+
806
  $missing_labels = false;
807
  $required_labels = array(
808
  'search',
813
  'results',
814
  'more',
815
  'directions',
816
+ 'no_directions',
817
  'back',
818
  'reset',
819
+ 'street_view',
820
+ 'zoom_here',
821
  'error',
822
  'phone',
823
  'fax',
890
  $msg = __( 'The Google Geocoding API returned no results for the store location. Please change the location and try again.', 'wpsl' );
891
  break;
892
  case 'OVER_QUERY_LIMIT':
893
+ $msg = sprintf( __( 'You have reached the daily allowed geocoding limit, you can read more <a href="%s">here</a>.', 'wpsl' ), 'https://developers.google.com/maps/documentation/geocoding/#Limits' );
894
  break;
895
  default:
896
  $msg = __( 'The Google Geocoding API failed to return valid data, please try again later.', 'wpsl' );
897
+ break;
898
  }
899
 
900
  if ( !empty( $msg ) ) {
910
  */
911
  public function get_latlng() {
912
 
913
+ $address = $this->store_data["address"].','.$this->store_data["city"].','.$this->store_data["zip"].','.$this->store_data["country"];
914
  $url = "http://maps.googleapis.com/maps/api/geocode/json?address=".urlencode( $address )."&sensor=false&language=".$this->settings['api_language'];
915
 
916
  if ( extension_loaded( "curl" ) && function_exists( "curl_init" ) ) {
939
  */
940
  public function filter_country_name( $response ) {
941
 
942
+ $length = count( $response['results'][0]['address_components'] );
943
 
944
  /* Loop over the address components untill we find the country,political part */
945
  for ( $i = 0; $i < $length; $i++ ) {
946
+ $address_component = $response['results'][0]['address_components'][$i]['types'];
947
 
948
  if ( $address_component[0] == 'country' && $address_component[1] == 'political' ) {
949
+ $country_name['long_name'] = $response['results'][0]['address_components'][$i]['long_name'];
950
+ $country_name['short_name'] = $response['results'][0]['address_components'][$i]['short_name'];
951
 
952
  break;
953
  }
1053
  * and set the active value to selected.
1054
  *
1055
  * @since 1.0
1056
+ * @todo generic dropdown function
1057
  * @return string $dropdown The html for the distance option list
1058
  */
1059
  public function show_distance_units() {
1073
 
1074
  return $dropdown;
1075
  }
1076
+
1077
+ /**
1078
+ * Create the default values for the marker clusters dropdown options
1079
+ *
1080
+ * @since 1.2.20
1081
+ * @param string $type The cluster option type
1082
+ * @return string $dropdown The default dropdown values
1083
+ */
1084
+ public function get_default_cluster_option( $type ) {
1085
+
1086
+ $cluster_values = array(
1087
+ 'cluster_zoom' => array(
1088
+ '7',
1089
+ '8',
1090
+ '9',
1091
+ '10',
1092
+ '11',
1093
+ '12',
1094
+ '13'
1095
+ ),
1096
+ 'cluster_size' => array(
1097
+ '40',
1098
+ '50',
1099
+ '60',
1100
+ '70',
1101
+ '80'
1102
+ ),
1103
+ );
1104
+
1105
+ return $cluster_values[$type];
1106
+ }
1107
+
1108
+ /**
1109
+ * Create a dropdown for the marker cluster options,
1110
+ *
1111
+ * @since 1.2.20
1112
+ * @todo move to generic dropdown function
1113
+ * @param string $type The cluster option type
1114
+ * @return string $dropdown The html for the distance option list
1115
+ */
1116
+ public function show_cluster_options( $type ) {
1117
+
1118
+ $cluster_options = array(
1119
+ 'cluster_zoom' => array(
1120
+ 'id' => 'wpsl-marker-zoom',
1121
+ 'name' => 'cluster_zoom',
1122
+ 'options' => $this->get_default_cluster_option( $type )
1123
+ ),
1124
+ 'cluster_size' => array(
1125
+ 'id' => 'wpsl-marker-cluster-size',
1126
+ 'name' => 'cluster_size',
1127
+ 'options' => $this->get_default_cluster_option( $type )
1128
+ ),
1129
+ );
1130
+
1131
+ $dropdown = '<select id="' . $cluster_options[$type]['id'] . '" name="wpsl_map[' . $cluster_options[$type]['name'] . ']">';
1132
+
1133
+ $i = 0;
1134
+ foreach ( $cluster_options[$type]['options'] as $item => $value ) {
1135
+ $selected = ( $this->settings[$type] == $value ) ? 'selected="selected"' : '';
1136
+
1137
+ if ( $i == 0 ) {
1138
+ $dropdown .= "<option value='0' $selected>" . __( 'Default', 'wpsl' ) . "</option>";
1139
+ } else {
1140
+ $dropdown .= "<option value='$value' $selected>" . $value . "</option>";
1141
+ }
1142
+
1143
+ $i++;
1144
+ }
1145
+
1146
+ $dropdown .= "</select>";
1147
+
1148
+ return $dropdown;
1149
+ }
1150
+
1151
+ /**
1152
+ * Show a list of available templates
1153
+ *
1154
+ * @since 1.2.20
1155
+ * @todo move to generic dropdown function
1156
+ * @return string $dropdown The html for the template option list
1157
+ */
1158
+ public function show_template_options() {
1159
+
1160
+ $dropdown = '<select id="wpsl-store-template" name="wpsl_design[template]">';
1161
+ $i = 0;
1162
+
1163
+ foreach ( $this->get_templates() as $template ) {
1164
+ $selected = ( $this->settings['template_id'] == $i ) ? ' selected="selected"' : '';
1165
+ $dropdown .= "<option value='" . $i . "' $selected>" . esc_attr( $template['name'] ) . "</option>";
1166
+ $i++;
1167
+ }
1168
+
1169
+ $dropdown .= "</select>";
1170
+
1171
+ return $dropdown;
1172
+ }
1173
 
1174
  /**
1175
  * Create a dropdown where users can select the used map type
1176
  *
1177
  * @since 1.0
1178
+ * @todo move to generic dropdown function
1179
  * @return string $dropdown The html for the map option list
1180
  */
1181
  public function show_map_types() {
1237
  * Create a dropdown where users can select location where the 'more info' data is shown
1238
  *
1239
  * @since 1.2.12
1240
+ * @todo generic dropdown function
1241
  * @return string $dropdown The html for the more info options list
1242
  */
1243
  public function show_more_info_options() {
1244
 
1245
  $items = array(
1246
+ 'store listings' => __( 'In the store listings', 'wpsl' ),
1247
+ 'info window' => __( 'In the info window on the map', 'wpsl' )
1248
  );
1249
  $dropdown = '<select id="wpsl-more-info-list" name="wpsl_design[more_info_location]">';
1250
 
1329
  break;
1330
  case 'region':
1331
  $api_option_list = array (
1332
+ __('Select your region', 'wpsl') => '',
1333
  __('Afghanistan', 'wpsl') => 'af',
1334
  __('Albania', 'wpsl') => 'al',
1335
  __('Algeria', 'wpsl') => 'dz',
1541
 
1542
  /* Make sure we have a array with a value */
1543
  if ( !empty( $api_option_list ) && ( is_array( $api_option_list ) ) ) {
1544
+ $option_list = '';
1545
  $i = 0;
1546
 
1547
  foreach ( $api_option_list as $api_option_key => $api_option_value ) {
1553
  $selected = ( $this->settings['api_'.$list] == $api_option_value ) ? 'selected="selected"' : '';
1554
  }
1555
 
1556
+ $option_list .= '<option value="' . esc_attr( $api_option_value ) . '" ' . $selected . '> ' . esc_html( $api_option_key ) . '</option>';
1557
  $i++;
1558
  }
1559
 
1578
  }
1579
  }
1580
 
1581
+ /**
1582
+ * Deregister other Google Maps scripts
1583
+ *
1584
+ * If plugins / themes also include the Google Maps library, and it is loaded after the
1585
+ * one from the Store Locator. It can break the autocomplete on the settings page.
1586
+ * To make sure this doesn't happen we look for other Google Maps scripts,
1587
+ * and if they exists we deregister them on the settings page.
1588
+ *
1589
+ * @since 1.2.20
1590
+ * @return void
1591
+ */
1592
+ public function deregister_other_gmaps() {
1593
+
1594
+ global $wp_scripts;
1595
+
1596
+ foreach ( $wp_scripts->registered as $index => $script ) {
1597
+ if ( ( strpos( $script->src, 'maps.google.com' ) !== false ) && ( $script->handle !== 'wpsl-gmap' ) ) {
1598
+ wp_deregister_script( $script->handle );
1599
+ }
1600
+ }
1601
+ }
1602
+
1603
+ /**
1604
+ * The warning messages used in wpsl-admin.js
1605
+ *
1606
+ * @since 1.2.20
1607
+ * @return array $admin_js_l10n The texts used in the wpsl-admin.js
1608
+ */
1609
+ public function admin_js_l10n() {
1610
+ $admin_js_l10n = array(
1611
+ 'noAddress' => __( 'Cannot determine the address at this location.', 'wpsl' ),
1612
+ 'geocodeFail' => __( 'Geocode was not successful for the following reason: ', 'wpsl' ),
1613
+ 'securityFail' => __( 'Security check failed, reload the page and try again.', 'wpsl' )
1614
+ );
1615
+
1616
+ return $admin_js_l10n;
1617
+ }
1618
+
1619
  /**
1620
  * Add the required admin script
1621
  *
1628
  wp_enqueue_style( 'jquery-style', '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css' );
1629
  wp_enqueue_style( 'wpsl-admin-css', plugins_url( '/css/style.css', __FILE__ ), false );
1630
  $this->check_icon_font_usage();
1631
+ wp_enqueue_script( 'wpsl-gmap', ( "//maps.google.com/maps/api/js?sensor=false&libraries=places&language=" . $this->settings['api_language'] ), false, '', true ); // we set the language here to make sure the geocode response returns the country name in the correct language
1632
  wp_enqueue_script( 'wpsl-admin-js', plugins_url( '/js/wpsl-admin.js', __FILE__ ), array( 'jquery' ), false );
1633
  wp_enqueue_script( 'wpsl-queue', plugins_url( '/js/ajax-queue.js', __FILE__ ), array( 'jquery' ), false );
1634
  wp_enqueue_script( 'wpsl-retina', plugins_url( '/js/retina-1.1.0.js', __FILE__ ), array( 'jquery' ), false );
1635
+
1636
+ wp_localize_script( 'wpsl-admin-js', 'wpslL10n', $this->admin_js_l10n() );
1637
+
1638
  }
1639
  }
1640
 
admin/class-store-overview.php CHANGED
@@ -17,7 +17,7 @@ class WPSL_Store_Overview extends WP_List_Table {
17
  * @since 1.0
18
  * @var string
19
  */
20
- private $_per_page = 10;
21
 
22
  /**
23
  * Class constructor
@@ -31,13 +31,35 @@ class WPSL_Store_Overview extends WP_List_Table {
31
  'plural' => __( 'Stores', 'wpsl' ),
32
  'ajax' => true
33
  ) );
 
 
34
  }
35
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  /**
37
  * The default message that is shown when no store data exists
38
  *
39
  * @since 1.0
40
- * @return string The default message
41
  */
42
  function no_items() {
43
  _e( 'No stores found', 'wpsl' );
@@ -56,7 +78,7 @@ class WPSL_Store_Overview extends WP_List_Table {
56
  switch( $column_name ) {
57
  case 'wpsl_id':
58
  case 'store':
59
- case 'street':
60
  case 'city':
61
  case 'state':
62
  case 'zip':
@@ -72,7 +94,7 @@ class WPSL_Store_Overview extends WP_List_Table {
72
  case 'active':
73
  return ( $item['active'] ) ? __( 'Active', 'wpsl' ) : __( 'Inactive', 'wpsl' );
74
  case 'action':
75
- return '<a class="button" href="' . admin_url( 'admin.php?page=wpsl_store_editor&action=edit_store&store_id=' . $item['wpsl_id'] ) . '">'. __( 'Edit', 'wpsl' ) . '</a><input type="button" class="button wpsl-delete-store-btn" name="text" value="Delete"><input name="wpsl_store_id" type="hidden" value="' . $item['wpsl_id'] . '" /><input name="wpsl_delete_nonce" type="hidden" value="' . wp_create_nonce( 'wpsl_delete_nonce_'.$item['wpsl_id'] ) . '" />';
76
  default:
77
  return 'wpsl_id';
78
  }
@@ -90,7 +112,7 @@ class WPSL_Store_Overview extends WP_List_Table {
90
  'wpsl_id' => array( 'wpsl_id', true ), //true = already sorted ( default )
91
  'thumb' => array( 'thumb', false ),
92
  'store' => array( 'store', false ),
93
- 'street' => array( 'street', false ),
94
  'city' => array( 'city', false ),
95
  'state' => array( 'state', false ),
96
  'zip' => array( 'zip', false ),
@@ -113,12 +135,12 @@ class WPSL_Store_Overview extends WP_List_Table {
113
  'wpsl_id' => __( 'ID', 'wpsl' ),
114
  'thumb' => __( 'Thumbnail', 'wpsl' ),
115
  'store' => __( 'Name', 'wpsl' ),
116
- 'street' => __( 'Address', 'wpsl' ),
117
  'city' => __( 'City', 'wpsl' ),
118
  'state' => __( 'State', 'wpsl' ),
119
  'zip' => __( 'Zip', 'wpsl' ),
120
  'active' => __( 'Status', 'wpsl' ),
121
- 'action' => __( 'Actions', 'wpsl' ),
122
  );
123
 
124
  return $columns;
@@ -146,9 +168,9 @@ class WPSL_Store_Overview extends WP_List_Table {
146
  function get_bulk_actions() {
147
 
148
  $actions = array(
149
- 'delete' => 'Delete',
150
- 'activate' => 'Activate',
151
- 'deactivate' => 'Deactivate'
152
  );
153
 
154
  return $actions;
@@ -167,23 +189,24 @@ class WPSL_Store_Overview extends WP_List_Table {
167
  global $wpdb;
168
 
169
  if ( $status === 'deactivate' ) {
170
- $active_status = 0;
171
  $success_action_desc = __( 'deactivated', 'wpsl' );
172
- $fail_action_desc = __( 'deactivating', 'wpsl' );
173
  } else {
174
- $active_status = 1;
175
  $success_action_desc = __( 'activated', 'wpsl' );
176
- $fail_action_desc = __( 'activating', 'wpsl' );
177
  }
178
 
179
  $result = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->wpsl_stores SET active = %d WHERE wpsl_id IN ( $store_ids )", $active_status ) );
180
 
181
  if ( $result === false ) {
182
  $state = 'error';
183
- $msg = __( 'There was a problem ' . $fail_action_desc . ' the store(s), please try again.', 'wpsl' );
 
184
  } else {
185
  $state = 'updated';
186
- $msg = __( 'Store(s) successfully ' . $success_action_desc , 'wpsl' );
187
  }
188
 
189
  add_settings_error ( 'bulk-state', esc_attr( 'bulk-state' ), $msg, $state );
@@ -204,10 +227,10 @@ class WPSL_Store_Overview extends WP_List_Table {
204
 
205
  if ( $result === false ) {
206
  $state = 'error';
207
- $msg = __( 'There was a problem removing the store(s), please try again.', 'wpsl' );
208
  } else {
209
  $state = 'updated';
210
- $msg = __( 'Store(s) successfully removed.' , 'wpsl' );
211
  }
212
 
213
  add_settings_error ( 'bulk-remove', esc_attr( 'bulk-remove' ), $msg, $state );
@@ -221,7 +244,7 @@ class WPSL_Store_Overview extends WP_List_Table {
221
  */
222
  function process_bulk_action() {
223
 
224
- if ( !current_user_can( 'manage_options' ) )
225
  die( '-1' );
226
 
227
  if ( isset( $_POST['_wpnonce'] ) && ! empty( $_POST['_wpnonce'] ) ) {
@@ -232,8 +255,9 @@ class WPSL_Store_Overview extends WP_List_Table {
232
  wp_die( 'Nope! Security check failed!' );
233
 
234
  $action = $this->current_action();
235
-
236
- if ( !empty ( $action ) ) {
 
237
  $id_list = array();
238
 
239
  foreach ( $_POST['store'] as $store_id ) {
@@ -269,26 +293,28 @@ class WPSL_Store_Overview extends WP_List_Table {
269
  function get_store_list() {
270
 
271
  global $wpdb;
 
 
272
 
273
  /* Check if we need to run the search query or just show all the data */
274
- if ( isset( $_POST['s'] ) ){
275
  $search = trim( $_POST['s'] );
276
  $result = $wpdb->get_results(
277
- $wpdb->prepare( "SELECT wpsl_id, store, street, city, state, zip, thumb_id AS thumb, active
278
  FROM $wpdb->wpsl_stores
279
- WHERE store LIKE %s OR street LIKE %s OR city LIKE %s OR state LIKE %s OR zip LIKE %s",
280
  '%' . like_escape( $search ). '%', '%' . like_escape( $search ). '%', '%' . like_escape( $search ). '%', '%' . like_escape( $search ). '%', '%' . like_escape( $search ). '%'
281
  ), ARRAY_A
282
  );
283
  } else {
284
  /* Order params */
285
- $orderby = !empty ( $_GET["orderby"] ) ? mysql_real_escape_string ( $_GET["orderby"] ) : 'store';
286
- $order = !empty ( $_GET["order"] ) ? mysql_real_escape_string ( $_GET["order"] ) : 'ASC';
287
  $order_sql = $orderby.' '.$order;
288
 
289
  /* Pagination parameters */
290
  $total_items = $wpdb->get_var( "SELECT COUNT(*) AS count FROM $wpdb->wpsl_stores" );
291
- $paged = !empty ( $_GET["paged"] ) ? mysql_real_escape_string ( $_GET["paged"] ) : '';
292
 
293
  if ( empty( $paged ) || !is_numeric( $paged ) || $paged <= 0 ) {
294
  $paged = 1;
@@ -297,11 +323,11 @@ class WPSL_Store_Overview extends WP_List_Table {
297
  $totalpages = ceil( $total_items / $this->_per_page );
298
 
299
  if ( !empty( $paged ) && !empty( $this->_per_page ) ){
300
- $offset = ( $paged - 1 ) * $this->_per_page;
301
  $limit_sql = (int)$offset.',' . (int)$this->_per_page;
302
  }
303
 
304
- $result = $wpdb->get_results( "SELECT wpsl_id, store, street, city, state, zip, thumb_id AS thumb, active FROM $wpdb->wpsl_stores ORDER BY $order_sql LIMIT $limit_sql", ARRAY_A );
305
  }
306
 
307
  $i = 0;
@@ -333,15 +359,15 @@ class WPSL_Store_Overview extends WP_List_Table {
333
  */
334
  function prepare_items() {
335
 
336
- $columns = $this->get_columns();
337
- $hidden = array();
338
  $sortable = $this->get_sortable_columns();
339
 
340
  $this->process_bulk_action();
341
  $response = $this->get_store_list();
342
 
343
  $current_page = $this->get_pagenum();
344
- $total_items = $response['count'];
345
 
346
  $this->set_pagination_args( array(
347
  'total_items' => $total_items,
17
  * @since 1.0
18
  * @var string
19
  */
20
+ private $_per_page;
21
 
22
  /**
23
  * Class constructor
31
  'plural' => __( 'Stores', 'wpsl' ),
32
  'ajax' => true
33
  ) );
34
+
35
+ $this->_per_page = $this->get_per_page();
36
  }
37
+
38
+ /**
39
+ * Get the per_page value from the option table
40
+ *
41
+ * @since 1.2.20
42
+ * @return string $per_page The amount of stores to show per page
43
+ */
44
+ function get_per_page() {
45
+
46
+ $user = get_current_user_id();
47
+ $screen = get_current_screen();
48
+ $option = $screen->get_option( 'per_page', 'option' );
49
+ $per_page = get_user_meta( $user, $option, true );
50
+
51
+ if ( empty( $per_page ) || $per_page < 1 ) {
52
+ $per_page = $screen->get_option( 'per_page', 'default' );
53
+ }
54
+
55
+ return $per_page;
56
+ }
57
+
58
  /**
59
  * The default message that is shown when no store data exists
60
  *
61
  * @since 1.0
62
+ * @return void
63
  */
64
  function no_items() {
65
  _e( 'No stores found', 'wpsl' );
78
  switch( $column_name ) {
79
  case 'wpsl_id':
80
  case 'store':
81
+ case 'address':
82
  case 'city':
83
  case 'state':
84
  case 'zip':
94
  case 'active':
95
  return ( $item['active'] ) ? __( 'Active', 'wpsl' ) : __( 'Inactive', 'wpsl' );
96
  case 'action':
97
+ return '<a class="button" href="' . admin_url( 'admin.php?page=wpsl_store_editor&action=edit_store&store_id=' . $item['wpsl_id'] ) . '">' . __( 'Edit', 'wpsl' ) . '</a><input type="button" class="button wpsl-delete-store-btn" name="text" value="' . __( 'Delete', 'wpsl' ) . '"><input name="wpsl_store_id" type="hidden" value="' . $item['wpsl_id'] . '" /><input name="wpsl_delete_nonce" type="hidden" value="' . wp_create_nonce( 'wpsl_delete_nonce_'.$item['wpsl_id'] ) . '" />';
98
  default:
99
  return 'wpsl_id';
100
  }
112
  'wpsl_id' => array( 'wpsl_id', true ), //true = already sorted ( default )
113
  'thumb' => array( 'thumb', false ),
114
  'store' => array( 'store', false ),
115
+ 'address' => array( 'address', false ),
116
  'city' => array( 'city', false ),
117
  'state' => array( 'state', false ),
118
  'zip' => array( 'zip', false ),
135
  'wpsl_id' => __( 'ID', 'wpsl' ),
136
  'thumb' => __( 'Thumbnail', 'wpsl' ),
137
  'store' => __( 'Name', 'wpsl' ),
138
+ 'address' => __( 'Address', 'wpsl' ),
139
  'city' => __( 'City', 'wpsl' ),
140
  'state' => __( 'State', 'wpsl' ),
141
  'zip' => __( 'Zip', 'wpsl' ),
142
  'active' => __( 'Status', 'wpsl' ),
143
+ 'action' => __( 'Actions', 'wpsl' )
144
  );
145
 
146
  return $columns;
168
  function get_bulk_actions() {
169
 
170
  $actions = array(
171
+ 'delete' => __( 'Delete', 'wpsl' ),
172
+ 'activate' => __( 'Activate', 'wpsl' ),
173
+ 'deactivate' => __( 'Deactivate', 'wpsl' )
174
  );
175
 
176
  return $actions;
189
  global $wpdb;
190
 
191
  if ( $status === 'deactivate' ) {
192
+ $active_status = 0;
193
  $success_action_desc = __( 'deactivated', 'wpsl' );
194
+ $fail_action_desc = __( 'deactivating', 'wpsl' );
195
  } else {
196
+ $active_status = 1;
197
  $success_action_desc = __( 'activated', 'wpsl' );
198
+ $fail_action_desc = __( 'activating', 'wpsl' );
199
  }
200
 
201
  $result = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->wpsl_stores SET active = %d WHERE wpsl_id IN ( $store_ids )", $active_status ) );
202
 
203
  if ( $result === false ) {
204
  $state = 'error';
205
+ $msg = sprintf( __( 'There was a problem %s the store(s), please try again.', 'wpsl' ), $fail_action_desc );
206
+
207
  } else {
208
  $state = 'updated';
209
+ $msg = sprintf( __( 'Store(s) successfully %s.', 'wpsl' ), $success_action_desc );
210
  }
211
 
212
  add_settings_error ( 'bulk-state', esc_attr( 'bulk-state' ), $msg, $state );
227
 
228
  if ( $result === false ) {
229
  $state = 'error';
230
+ $msg = __( 'There was a problem removing the store(s), please try again.', 'wpsl' );
231
  } else {
232
  $state = 'updated';
233
+ $msg = __( 'Store(s) successfully removed.' , 'wpsl' );
234
  }
235
 
236
  add_settings_error ( 'bulk-remove', esc_attr( 'bulk-remove' ), $msg, $state );
244
  */
245
  function process_bulk_action() {
246
 
247
+ if ( !current_user_can( apply_filters( 'wpsl_capability', 'manage_options' ) ) )
248
  die( '-1' );
249
 
250
  if ( isset( $_POST['_wpnonce'] ) && ! empty( $_POST['_wpnonce'] ) ) {
255
  wp_die( 'Nope! Security check failed!' );
256
 
257
  $action = $this->current_action();
258
+
259
+ /* If an action is set continue, otherwise reload the page */
260
+ if ( !empty( $action ) ) {
261
  $id_list = array();
262
 
263
  foreach ( $_POST['store'] as $store_id ) {
293
  function get_store_list() {
294
 
295
  global $wpdb;
296
+
297
+ $total_items = 0;
298
 
299
  /* Check if we need to run the search query or just show all the data */
300
+ if ( isset( $_POST['s'] ) && ( !empty( $_POST['s'] ) ) ) {
301
  $search = trim( $_POST['s'] );
302
  $result = $wpdb->get_results(
303
+ $wpdb->prepare( "SELECT wpsl_id, store, address, city, state, zip, thumb_id AS thumb, active
304
  FROM $wpdb->wpsl_stores
305
+ WHERE store LIKE %s OR address LIKE %s OR city LIKE %s OR state LIKE %s OR zip LIKE %s",
306
  '%' . like_escape( $search ). '%', '%' . like_escape( $search ). '%', '%' . like_escape( $search ). '%', '%' . like_escape( $search ). '%', '%' . like_escape( $search ). '%'
307
  ), ARRAY_A
308
  );
309
  } else {
310
  /* Order params */
311
+ $orderby = !empty ( $_GET["orderby"] ) ? mysql_real_escape_string ( $_GET["orderby"] ) : 'store';
312
+ $order = !empty ( $_GET["order"] ) ? mysql_real_escape_string ( $_GET["order"] ) : 'ASC';
313
  $order_sql = $orderby.' '.$order;
314
 
315
  /* Pagination parameters */
316
  $total_items = $wpdb->get_var( "SELECT COUNT(*) AS count FROM $wpdb->wpsl_stores" );
317
+ $paged = !empty ( $_GET["paged"] ) ? mysql_real_escape_string ( $_GET["paged"] ) : '';
318
 
319
  if ( empty( $paged ) || !is_numeric( $paged ) || $paged <= 0 ) {
320
  $paged = 1;
323
  $totalpages = ceil( $total_items / $this->_per_page );
324
 
325
  if ( !empty( $paged ) && !empty( $this->_per_page ) ){
326
+ $offset = ( $paged - 1 ) * $this->_per_page;
327
  $limit_sql = (int)$offset.',' . (int)$this->_per_page;
328
  }
329
 
330
+ $result = $wpdb->get_results( "SELECT wpsl_id, store, address, city, state, zip, thumb_id AS thumb, active FROM $wpdb->wpsl_stores ORDER BY $order_sql LIMIT $limit_sql", ARRAY_A );
331
  }
332
 
333
  $i = 0;
359
  */
360
  function prepare_items() {
361
 
362
+ $columns = $this->get_columns();
363
+ $hidden = array();
364
  $sortable = $this->get_sortable_columns();
365
 
366
  $this->process_bulk_action();
367
  $response = $this->get_store_list();
368
 
369
  $current_page = $this->get_pagenum();
370
+ $total_items = $response['count'];
371
 
372
  $this->set_pagination_args( array(
373
  'total_items' => $total_items,
admin/css/style-3.8.css CHANGED
@@ -26,4 +26,8 @@
26
  /* Hide the pre 3.8 menu icon */
27
  #adminmenu #toplevel_page_wpsl_store_editor .wp-menu-image img {
28
  display:none;
 
 
 
 
29
  }
26
  /* Hide the pre 3.8 menu icon */
27
  #adminmenu #toplevel_page_wpsl_store_editor .wp-menu-image img {
28
  display:none;
29
+ }
30
+
31
+ #wpsl-store-overview .widefat td.thumb {
32
+ padding-top:8px;
33
  }
admin/css/style.css CHANGED
@@ -9,7 +9,7 @@
9
  }
10
 
11
  #wpsl-store-overview .widefat td.thumb {
12
- padding:6px 0 0 8px;
13
  }
14
 
15
  #wpsl-store-overview .thumb img {
@@ -225,5 +225,10 @@
225
  }
226
 
227
  #wpsl-faq dl {
228
- margin-bottom: 17px;
 
 
 
 
 
229
  }
9
  }
10
 
11
  #wpsl-store-overview .widefat td.thumb {
12
+ padding:9px 0 0 8px;
13
  }
14
 
15
  #wpsl-store-overview .thumb img {
225
  }
226
 
227
  #wpsl-faq dl {
228
+ margin-bottom: 25px;
229
+ }
230
+
231
+ /* Overview page */
232
+ .wp-list-table .column-action .button {
233
+ margin:3px 5px 3px 0;
234
  }
admin/js/wpsl-admin.js CHANGED
@@ -12,7 +12,7 @@ function initializeGmap() {
12
  };
13
 
14
  geocoder = new google.maps.Geocoder();
15
- map = new google.maps.Map( document.getElementById( "wpsl-gmap-wrap" ), myOptions );
16
 
17
  checkEditStoreMarker();
18
  }
@@ -74,23 +74,12 @@ function geocodeDraggedPosition( pos ) {
74
  }, function ( response ) {
75
  if ( response && response.length > 0 ) {
76
  setLatlng( response[0].geometry.location, "store" );
77
-
78
- /* Set the zip code, but only if no existing value exists */
79
- setZipCode( response );
80
  } else {
81
- alert( "Cannot determine address at this location." );
82
  }
83
  });
84
  }
85
 
86
- /* Only update the zipcode if there is no existing value */
87
- function setZipCode( response ) {
88
- if ( !$( "#wpsl-store-zip" ).val() ) {
89
- var filteredResponse = filterApiResponse( response );
90
- $( "#wpsl-store-zip" ).val( filteredResponse.zip );
91
- }
92
- }
93
-
94
  /* Lookup the provided location name with the Google Maps API */
95
  $( "#wpsl-lookup-location" ).on( "click", function() {
96
  codeAddress();
@@ -100,15 +89,15 @@ $( "#wpsl-lookup-location" ).on( "click", function() {
100
  /* Geocode the user input */
101
  function codeAddress() {
102
  var filteredResponse,
103
- street = $( "#wpsl-store-street" ).val(),
104
  city = $( "#wpsl-store-city" ).val(),
105
  zip = $( "#wpsl-store-zip" ).val(),
106
  country = $( "#wpsl-store-country" ).val(),
107
- address = street + ',' + city + ',' + zip + ',' + country;
108
 
109
  /* Check we have all the requird data before attempting to geocode the address */
110
- if ( !validatePreviewFields( street, city, zip, country ) ) {
111
- geocoder.geocode( { 'address': address }, function( response, status ) {
112
  if ( status === google.maps.GeocoderStatus.OK ) {
113
 
114
  /* If we have a previous marker on the map remove it */
@@ -126,24 +115,23 @@ function codeAddress() {
126
  setLatlng( response[0].geometry.location, "store" );
127
 
128
  filteredResponse = filterApiResponse( response );
129
- $( "#wpsl-store-zip" ).val( filteredResponse.zip );
130
  $( "#wpsl-store-country" ).val( filteredResponse.country.long_name );
131
  $( "#wpsl-country-iso" ).val( filteredResponse.country.short_name );
132
  } else {
133
- alert( "Geocode was not successful for the following reason: " + status );
134
  }
135
  });
136
  }
137
  }
138
 
139
  /* Check that all required fields for the preview to work are there */
140
- function validatePreviewFields( street, city, zip, country ) {
141
  var error = false;
142
 
143
  $( "#wpsl-wrap input" ).removeClass( "wpsl-error" );
144
 
145
- if ( !street ) {
146
- $( "#wpsl-store-street" ).addClass( "wpsl-error" );
147
  error = true;
148
  }
149
 
@@ -167,7 +155,7 @@ function validatePreviewFields( street, city, zip, country ) {
167
 
168
  /* Filter out the zipcode from the Google Maps API response */
169
  function filterApiResponse( response ) {
170
- var zipcode, responseType,
171
  country = {},
172
  collectedData = {},
173
  addressLength = response[0].address_components.length;
@@ -183,15 +171,9 @@ function filterApiResponse( response ) {
183
  short_name : response[0].address_components[i].short_name
184
  };
185
  }
186
-
187
- /* filter out the postal code */
188
- if ( ( /^postal_code$/.test( responseType ) ) || ( /^postal_code_prefix,postal_code$/.test( responseType ) ) ) {
189
- zipcode = response[0].address_components[i].long_name;
190
- }
191
  }
192
 
193
  collectedData = {
194
- zip : zipcode,
195
  country : country
196
  };
197
 
@@ -295,8 +277,8 @@ $( ".wpsl-delete-store-btn" ).removeAttr( "disabled" );
295
  $( "#wpsl-store-overview" ).on( "click", ".wpsl-delete-store-btn", function() {
296
  var elem = $(this),
297
  dialogBox = $( "#wpsl-delete-confirmation" ),
298
- cancelBtn = dialogBox.find( ".button-secondary" ),
299
- submitBtn = dialogBox.find( ".button-primary" );
300
 
301
  dialogBox.dialog({
302
  width: 325,
@@ -345,13 +327,18 @@ function deleteStore( elem ) {
345
  if ( response === -1 ) {
346
  elem.removeAttr( "disabled" );
347
  $( ".wpsl-preloader" ).remove();
348
- alert( "Security check failed, reload the page and try again." );
349
  } else if ( response.success ) {
 
 
350
  setTimeout( function() {
351
  $parentTr.fadeOut( "200", function() {
352
  $parentTr.remove();
 
 
 
353
  });
354
- }, 2000);
355
  }
356
  });
357
  }
@@ -395,13 +382,40 @@ $( "#wpsl-more-info" ).on( "change", function() {
395
  $( "#wpsl-more-info-options" ).toggle();
396
  });
397
 
398
- /* Detect changes for the store listings display option, either show below the map or not.
399
- * If so, then show the option to remove the scrollbar
400
  */
401
- $( "#wpsl-store-below" ).on( "change", function() {
402
- $( "#wpsl-store-below-scroll" ).toggle();
 
 
 
 
 
 
 
 
 
 
 
403
  });
404
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  /* Load the map */
406
  if ( $( "#wpsl-gmap-wrap" ).length ) {
407
  google.maps.event.addDomListener( window, "load", initializeGmap );
12
  };
13
 
14
  geocoder = new google.maps.Geocoder();
15
+ map = new google.maps.Map( document.getElementById( "wpsl-gmap-wrap" ), myOptions );
16
 
17
  checkEditStoreMarker();
18
  }
74
  }, function ( response ) {
75
  if ( response && response.length > 0 ) {
76
  setLatlng( response[0].geometry.location, "store" );
 
 
 
77
  } else {
78
+ alert( wpslL10n.noAddress );
79
  }
80
  });
81
  }
82
 
 
 
 
 
 
 
 
 
83
  /* Lookup the provided location name with the Google Maps API */
84
  $( "#wpsl-lookup-location" ).on( "click", function() {
85
  codeAddress();
89
  /* Geocode the user input */
90
  function codeAddress() {
91
  var filteredResponse,
92
+ address = $( "#wpsl-store-address" ).val(),
93
  city = $( "#wpsl-store-city" ).val(),
94
  zip = $( "#wpsl-store-zip" ).val(),
95
  country = $( "#wpsl-store-country" ).val(),
96
+ fullAddress = address + ',' + city + ',' + zip + ',' + country;
97
 
98
  /* Check we have all the requird data before attempting to geocode the address */
99
+ if ( !validatePreviewFields( address, city, zip, country ) ) {
100
+ geocoder.geocode( { 'address': fullAddress }, function( response, status ) {
101
  if ( status === google.maps.GeocoderStatus.OK ) {
102
 
103
  /* If we have a previous marker on the map remove it */
115
  setLatlng( response[0].geometry.location, "store" );
116
 
117
  filteredResponse = filterApiResponse( response );
 
118
  $( "#wpsl-store-country" ).val( filteredResponse.country.long_name );
119
  $( "#wpsl-country-iso" ).val( filteredResponse.country.short_name );
120
  } else {
121
+ alert( wpslL10n.geocodeFail + ' ' + status );
122
  }
123
  });
124
  }
125
  }
126
 
127
  /* Check that all required fields for the preview to work are there */
128
+ function validatePreviewFields( address, city, zip, country ) {
129
  var error = false;
130
 
131
  $( "#wpsl-wrap input" ).removeClass( "wpsl-error" );
132
 
133
+ if ( !address ) {
134
+ $( "#wpsl-store-address" ).addClass( "wpsl-error" );
135
  error = true;
136
  }
137
 
155
 
156
  /* Filter out the zipcode from the Google Maps API response */
157
  function filterApiResponse( response ) {
158
+ var responseType,
159
  country = {},
160
  collectedData = {},
161
  addressLength = response[0].address_components.length;
171
  short_name : response[0].address_components[i].short_name
172
  };
173
  }
 
 
 
 
 
174
  }
175
 
176
  collectedData = {
 
177
  country : country
178
  };
179
 
277
  $( "#wpsl-store-overview" ).on( "click", ".wpsl-delete-store-btn", function() {
278
  var elem = $(this),
279
  dialogBox = $( "#wpsl-delete-confirmation" ),
280
+ cancelBtn = dialogBox.find( ".button-secondary" ),
281
+ submitBtn = dialogBox.find( ".button-primary" );
282
 
283
  dialogBox.dialog({
284
  width: 325,
327
  if ( response === -1 ) {
328
  elem.removeAttr( "disabled" );
329
  $( ".wpsl-preloader" ).remove();
330
+ alert( wpslL10n.securityFail );
331
  } else if ( response.success ) {
332
+
333
+ /* Remove the deleted store row */
334
  setTimeout( function() {
335
  $parentTr.fadeOut( "200", function() {
336
  $parentTr.remove();
337
+
338
+ /* Update the remaining store count */
339
+ updateStoreCount();
340
  });
341
+ }, 2000);
342
  }
343
  });
344
  }
382
  $( "#wpsl-more-info-options" ).toggle();
383
  });
384
 
385
+ /* Detect changes to the store template dropdown. If the template is selected to
386
+ * show the store list under the map then we show the option to hide the scrollbar.
387
  */
388
+ $( "#wpsl-store-template" ).on( "change", function() {
389
+ var $scrollOption = $( "#wpsl-store-below-scroll" );
390
+
391
+ if ( $( "#wpsl-store-template" ).val() == "1" ) {
392
+ $scrollOption.show();
393
+ } else {
394
+ $scrollOption.hide();
395
+ }
396
+ });
397
+
398
+ /* If the marker cluster checkbox changes, show/hide the options */
399
+ $( "#wpsl-marker-clusters" ).on( "change", function() {
400
+ $( ".wpsl-cluster-options" ).toggle();
401
  });
402
 
403
+ /**
404
+ * When a store is deleted, update the store count that is
405
+ * shown above and below the store overview list
406
+ *
407
+ * @since 1.2.20
408
+ * @return void
409
+ */
410
+ function updateStoreCount() {
411
+ var pageNum = $( ".tablenav.top .displaying-num" ).text(),
412
+ pageNum = pageNum.split( " " );
413
+
414
+ if ( !isNaN( parseInt( pageNum[0] ) ) ) {
415
+ $( ".tablenav .displaying-num" ).text( pageNum[0]-1 + ' ' + pageNum[1] );
416
+ }
417
+ }
418
+
419
  /* Load the map */
420
  if ( $( "#wpsl-gmap-wrap" ).length ) {
421
  google.maps.event.addDomListener( window, "load", initializeGmap );
admin/misc-functions.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ add_action( 'plugins_loaded', 'add_wpsl_screen_filter' );
3
+
4
+ /**
5
+ * Add the filter to save the visible store value
6
+ *
7
+ * @since 1.2.20
8
+ * @return void
9
+ */
10
+ function add_wpsl_screen_filter() {
11
+ add_filter( 'set-screen-option', 'set_wpsl_screen_option', 10, 3 );
12
+ }
13
+
14
+ /**
15
+ * Save the wpsl screen options
16
+ *
17
+ * Users can define the amount of visible stores
18
+ *
19
+ * @since 1.2.20
20
+ * @param bool|int $status Screen option value. Default false to skip.
21
+ * @param string $option The option name.
22
+ * @param int $value The number of rows to use.
23
+ * @return bool|int $value|$status
24
+ */
25
+ function set_wpsl_screen_option( $status, $option, $value ) {
26
+
27
+ if ( 'wpsl_stores_per_page' == $option ) return $value;
28
+
29
+ return $status;
30
+ }
admin/templates/add-store.php CHANGED
@@ -2,11 +2,7 @@
2
  <h2>WP Store Locator</h2>
3
  <?php settings_errors(); ?>
4
 
5
- <ul id="wpsl-mainnav" class="nav-tab-wrapper">
6
- <li><a class="nav-tab" href="<?php echo admin_url( 'admin.php?page=wpsl_store_editor' ); ?>"><?php _e('Current Stores', 'wpsl'); ?></a></li>
7
- <li><a class="nav-tab nav-tab-active" href="<?php echo admin_url( 'admin.php?page=wpsl_add_store' ); ?>"><?php _e('Add Store', 'wpsl'); ?></a></li>
8
- <li><a class="nav-tab" href="<?php echo admin_url( 'admin.php?page=wpsl_settings' ); ?>"><?php _e( 'Settings', 'wpsl' ); ?></a></li>
9
- </ul>
10
 
11
  <form method="post" action="" accept-charset="utf-8">
12
  <input type="hidden" name="wpsl_actions" value="add_new_store" />
@@ -18,15 +14,19 @@
18
  <div class="inside">
19
  <p>
20
  <label for="wpsl-store-name"><?php _e( 'Store Name:', 'wpsl' ); ?></label>
21
- <input id="wpsl-store-name" name="wpsl[store]" type="text" class="textinput <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['store'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( !empty( $_POST['wpsl']['store'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['store'] ) ); } ?>" />
22
  </p>
23
  <p>
24
- <label for="wpsl-store-street"><?php _e( 'Street:', 'wpsl' ); ?></label>
25
- <input id="wpsl-store-street" name="wpsl[street]" type="text" class="textinput <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['street'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( !empty( $_POST['wpsl']['street'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['street'] ) ); } ?>" />
 
 
 
 
26
  </p>
27
  <p>
28
  <label for="wpsl-store-city"><?php _e( 'City:', 'wpsl' ); ?></label>
29
- <input id="wpsl-store-city" name="wpsl[city]" type="text" class="textinput <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['city'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( !empty( $_POST['wpsl']['city'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['city'] ) ); } ?>" />
30
  </p>
31
  <p>
32
  <label for="wpsl-store-state"><?php _e( 'State / Province:', 'wpsl' ); ?></label>
@@ -34,11 +34,11 @@
34
  </p>
35
  <p>
36
  <label for="wpsl-store-zip"><?php _e( 'Zip Code:', 'wpsl' ); ?></label>
37
- <input id="wpsl-store-zip" name="wpsl[zip]" type="text" class="textinput <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['zip'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( !empty( $_POST['wpsl']['zip'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['zip'] ) ); } ?>" />
38
  </p>
39
  <p>
40
  <label for="wpsl-store-country"><?php _e( 'Country:', 'wpsl' ); ?></label>
41
- <input id="wpsl-store-country" name="wpsl[country]" type="text" class="textinput <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['country'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( !empty( $_POST['wpsl']['country'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['country'] ) ); } ?>" />
42
  <input id="wpsl-country-iso" type="hidden" name="wpsl[country-iso]" value="<?php if ( !empty( $_POST['wpsl']['country-iso'] ) ) { echo esc_attr( $_POST['wpsl']['country-iso'] ); } ?>" />
43
  </p>
44
  <p>
@@ -51,7 +51,7 @@
51
  </p>
52
  <p class="wpsl-submit-wrap">
53
  <input id="wpsl-lookup-location" type="submit" name="wpsl-lookup-location" class="button-primary" value="<?php _e( 'Preview location on the map', 'wpsl' ); ?>" />
54
- <em class="nwm-desc"><?php _e( 'You can adjust the location by dragging the marker around', 'nwm' ); ?></em>
55
  </p>
56
  </div>
57
  </div>
@@ -88,6 +88,7 @@
88
  <label for="wpsl-store-hours"><?php _e( 'Operation Hours:', 'wpsl' ); ?></label>
89
  <textarea id="wpsl-store-hours" name="wpsl[hours]" cols="5" rows="5"><?php if ( !empty( $_POST['wpsl']['hours'] ) ) { echo esc_textarea( stripslashes( $_POST['wpsl']['hours'] ) ); } ?></textarea>
90
  </p>
 
91
  <div id="wpsl-thumb-wrap">
92
  <p>
93
  <label><?php _e( 'Thumbnail:', 'wpsl' ); ?></label>
@@ -99,6 +100,7 @@
99
  <input type="hidden" id="wpsl-thumb-id" name="wpsl[thumb-id]" value="" />
100
  </div>
101
  </div>
 
102
  </div>
103
  </div>
104
 
2
  <h2>WP Store Locator</h2>
3
  <?php settings_errors(); ?>
4
 
5
+ <?php echo $this->create_menu(); ?>
 
 
 
 
6
 
7
  <form method="post" action="" accept-charset="utf-8">
8
  <input type="hidden" name="wpsl_actions" value="add_new_store" />
14
  <div class="inside">
15
  <p>
16
  <label for="wpsl-store-name"><?php _e( 'Store Name:', 'wpsl' ); ?></label>
17
+ <input id="wpsl-store-name" name="wpsl[store]" type="text" class="textinput <?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['store'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( !empty( $_POST['wpsl']['store'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['store'] ) ); } ?>" />
18
  </p>
19
  <p>
20
+ <label for="wpsl-store-address"><?php _e( 'Address:', 'wpsl' ); ?></label>
21
+ <input id="wpsl-store-address" name="wpsl[address]" type="text" class="textinput <?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['address'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( !empty( $_POST['wpsl']['address'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['address'] ) ); } ?>" />
22
+ </p>
23
+ <p>
24
+ <label for="wpsl-store-address2"><?php _e( 'Address 2:', 'wpsl' ); ?></label>
25
+ <input id="wpsl-store-address2" name="wpsl[address2]" type="text" class="textinput" value="<?php if ( !empty( $_POST['wpsl']['address2'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['address2'] ) ); } ?>" />
26
  </p>
27
  <p>
28
  <label for="wpsl-store-city"><?php _e( 'City:', 'wpsl' ); ?></label>
29
+ <input id="wpsl-store-city" name="wpsl[city]" type="text" class="textinput <?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['city'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( !empty( $_POST['wpsl']['city'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['city'] ) ); } ?>" />
30
  </p>
31
  <p>
32
  <label for="wpsl-store-state"><?php _e( 'State / Province:', 'wpsl' ); ?></label>
34
  </p>
35
  <p>
36
  <label for="wpsl-store-zip"><?php _e( 'Zip Code:', 'wpsl' ); ?></label>
37
+ <input id="wpsl-store-zip" name="wpsl[zip]" type="text" class="textinput <?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['zip'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( !empty( $_POST['wpsl']['zip'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['zip'] ) ); } ?>" />
38
  </p>
39
  <p>
40
  <label for="wpsl-store-country"><?php _e( 'Country:', 'wpsl' ); ?></label>
41
+ <input id="wpsl-store-country" name="wpsl[country]" type="text" class="textinput <?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['country'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( !empty( $_POST['wpsl']['country'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['country'] ) ); } else { echo esc_attr( stripslashes( $this->settings['editor_country'] ) ); } ?>" />
42
  <input id="wpsl-country-iso" type="hidden" name="wpsl[country-iso]" value="<?php if ( !empty( $_POST['wpsl']['country-iso'] ) ) { echo esc_attr( $_POST['wpsl']['country-iso'] ); } ?>" />
43
  </p>
44
  <p>
51
  </p>
52
  <p class="wpsl-submit-wrap">
53
  <input id="wpsl-lookup-location" type="submit" name="wpsl-lookup-location" class="button-primary" value="<?php _e( 'Preview location on the map', 'wpsl' ); ?>" />
54
+ <em class="nwm-desc"><?php _e( 'You can adjust the location by dragging the marker around', 'wpsl' ); ?></em>
55
  </p>
56
  </div>
57
  </div>
88
  <label for="wpsl-store-hours"><?php _e( 'Operation Hours:', 'wpsl' ); ?></label>
89
  <textarea id="wpsl-store-hours" name="wpsl[hours]" cols="5" rows="5"><?php if ( !empty( $_POST['wpsl']['hours'] ) ) { echo esc_textarea( stripslashes( $_POST['wpsl']['hours'] ) ); } ?></textarea>
90
  </p>
91
+ <?php if ( current_user_can( 'upload_files' ) ) { ?>
92
  <div id="wpsl-thumb-wrap">
93
  <p>
94
  <label><?php _e( 'Thumbnail:', 'wpsl' ); ?></label>
100
  <input type="hidden" id="wpsl-thumb-id" name="wpsl[thumb-id]" value="" />
101
  </div>
102
  </div>
103
+ <?php } ?>
104
  </div>
105
  </div>
106
 
admin/templates/edit-store.php CHANGED
@@ -11,7 +11,7 @@ if ( $store_id ) {
11
  }
12
  ?>
13
  <div id="wpsl-wrap" class="wrap wpsl-add-stores">
14
- <h2 class="wpsl-edit-header">Edit <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['store'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['store'] ) ); } else { echo esc_attr( stripslashes( $store_details['store'] ) ); } ?></h2>
15
  <?php settings_errors(); ?>
16
 
17
  <form method="post" action="" accept-charset="utf-8">
@@ -33,36 +33,40 @@ if ( $store_id ) {
33
  </p>
34
  <p>
35
  <label for="wpsl-store-name"><?php _e( 'Store Name:', 'wpsl' ); ?></label>
36
- <input id="wpsl-store-name" name="wpsl[store]" type="text" class="textinput <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['store'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['store'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['store'] ) ); } else { echo esc_attr( stripslashes( $store_details['store'] ) ); } ?>" />
37
  </p>
38
  <p>
39
- <label for="wpsl-store-street"><?php _e( 'Street:', 'wpsl' ); ?></label>
40
- <input id="wpsl-store-street" name="wpsl[street]" type="text" class="textinput <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['street'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['street'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['street'] ) ); } else { echo esc_attr( stripslashes( $store_details['street'] ) ); } ?>" />
 
 
 
 
41
  </p>
42
  <p>
43
  <label for="wpsl-store-city"><?php _e( 'City:', 'wpsl' ); ?></label>
44
- <input id="wpsl-store-city" name="wpsl[city]" type="text" class="textinput <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['city'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['city'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['city'] ) ); } else { echo esc_attr( stripslashes( $store_details['city'] ) ); } ?>" />
45
  </p>
46
  <p>
47
  <label for="wpsl-store-state"><?php _e( 'State / Province:', 'wpsl' ); ?></label>
48
- <input id="wpsl-store-state" name="wpsl[state]" type="text" class="textinput" value="<?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['state'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['state'] ) ); } else { echo esc_attr( stripslashes( $store_details['state'] ) ); } ?>" />
49
  </p>
50
  <p>
51
  <label for="wpsl-store-zip"><?php _e( 'Zip Code:', 'wpsl' ); ?></label>
52
- <input id="wpsl-store-zip" name="wpsl[zip]" type="text" class="textinput <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['zip'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['zip'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['zip'] ) ); } else { echo esc_attr( stripslashes( $store_details['zip'] ) ); } ?>" />
53
  </p>
54
  <p>
55
  <label for="wpsl-store-country"><?php _e( 'Country:', 'wpsl' ); ?></label>
56
- <input id="wpsl-store-country" name="wpsl[country]" type="text" class="textinput <?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['country'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['country'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['country'] ) ); } else { echo esc_attr( stripslashes( $store_details['country'] ) ); } ?>" />
57
  <input id="wpsl-country-iso" type="hidden" name="wpsl[country-iso]" value="<?php echo esc_attr( $store_details['country_iso'] ); ?>" />
58
  </p>
59
  <p>
60
  <label for="wpsl-store-lat"><?php _e( 'Latitude:', 'wpsl' ); ?></label>
61
- <input id="wpsl-store-lat" name="wpsl[lat]" type="text" class="textinput" value="<?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['lat'] ) ) { echo esc_attr( $_POST['wpsl']['lat'] ); } else { echo esc_attr( $store_details['lat'] ); } ?>" />
62
  </p>
63
  <p>
64
  <label for="wpsl-store-lng"><?php _e( 'Longitude:', 'wpsl' ); ?></label>
65
- <input id="wpsl-store-lng" name="wpsl[lng]" type="text" class="textinput" value="<?php if ( ( $_POST['wpsl'] ) && empty( $_POST['wpsl']['lng'] ) ) { echo esc_attr( $_POST['wpsl']['lng'] ); } else { echo esc_attr( $store_details['lng'] ); } ?>" />
66
  </p>
67
  <p class="wpsl-submit-wrap">
68
  <input id="wpsl-lookup-location" type="submit" name="wpsl-lookup-location" class="button-primary" value="<?php _e( 'Preview location on the map', 'wpsl' ); ?>" />
@@ -81,28 +85,29 @@ if ( $store_id ) {
81
  <div class="inside">
82
  <p>
83
  <label for="wpsl-store-phone"><?php _e( 'Phone:', 'wpsl' ); ?></label>
84
- <input id="wpsl-store-phone" name="wpsl[phone]" type="text" class="textinput" value="<?php if ( $_POST['wpsl']['phone'] ) { echo esc_attr( $_POST['wpsl']['phone'] ); } else { echo esc_attr( $store_details['phone'] ); } ?>">
85
  </p>
86
  <p>
87
  <label for="wpsl-store-fax"><?php _e( 'Fax:', 'wpsl' ); ?></label>
88
- <input id="wpsl-store-fax" name="wpsl[fax]" type="text" class="textinput" value="<?php if ( $_POST['wpsl']['fax'] ) { echo esc_attr( $_POST['wpsl']['fax'] ); } else { echo esc_attr( $store_details['fax'] ); } ?>">
89
  </p>
90
  <p>
91
  <label for="wpsl-store-email"><?php _e( 'Email:', 'wpsl' ); ?></label>
92
- <input id="wpsl-store-email" name="wpsl[email]" type="email" class="textinput" value="<?php if ( $_POST['wpsl']['email'] ) { echo esc_attr( $_POST['wpsl']['email'] ); } else { echo esc_attr( $store_details['email'] ); } ?>">
93
  </p>
94
  <p>
95
  <label for="wpsl-store-url"><?php _e( 'Url:', 'wpsl' ); ?></label>
96
- <input id="wpsl-store-url" name="wpsl[url]" type="url" class="textinput" value="<?php if ( $_POST['wpsl']['url'] ) { echo esc_url( $_POST['wpsl']['url'] ); } else { echo esc_url( $store_details['url'] ); } ?>">
97
  </p>
98
  <p>
99
  <label for="wpsl-store-desc"><?php _e( 'Description:', 'wpsl' ); ?></label>
100
- <textarea id="wpsl-store-desc" name="wpsl[desc]" cols="5" rows="5"><?php if ( $_POST['wpsl']['desc'] ) { echo esc_textarea( stripslashes( $_POST['wpsl']['desc'] ) ); } else { echo esc_textarea( stripslashes( $store_details['description'] ) ); } ?></textarea>
101
  </p>
102
  <p>
103
  <label for="wpsl-store-hours"><?php _e( 'Operation Hours:', 'wpsl' ); ?></label>
104
- <textarea id="wpsl-store-hours" name="wpsl[hours]" cols="5" rows="5"><?php if ( $_POST['wpsl']['hours'] ) { echo esc_textarea( stripslashes( $_POST['wpsl']['hours'] ) ); } else { echo esc_textarea( stripslashes( $store_details['hours'] ) ); } ?></textarea>
105
  </p>
 
106
  <div id="wpsl-thumb-wrap">
107
  <p>
108
  <label><?php _e( 'Thumbnail:', 'wpsl' ); ?></label>
@@ -122,12 +127,12 @@ if ( $store_id ) {
122
  <input type="hidden" id="wpsl-thumb-id" name="wpsl[thumb-id]" value="<?php echo esc_attr( $store_details['thumb_id'] ); ?>" />
123
  </div>
124
  </div>
 
125
  </div>
126
  </div>
127
 
128
  <p>
129
  <input id="wpsl-update-store" type="submit" name="wpsl-update-store" class="button-primary" value="<?php _e( 'Update Store', 'wpsl' ); ?>" />
130
- <input id="wpsl-delete-store" type="submit" name="wpsl-delete-store" class="button-primary" value="<?php _e( 'Delete Store', 'wpsl' ); ?>" />
131
  </p>
132
  </div>
133
  </form>
11
  }
12
  ?>
13
  <div id="wpsl-wrap" class="wrap wpsl-add-stores">
14
+ <h2 class="wpsl-edit-header"><?php _e( 'Edit ', 'wpsl' ); if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['store'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['store'] ) ); } else { echo esc_attr( stripslashes( $store_details['store'] ) ); } ?></h2>
15
  <?php settings_errors(); ?>
16
 
17
  <form method="post" action="" accept-charset="utf-8">
33
  </p>
34
  <p>
35
  <label for="wpsl-store-name"><?php _e( 'Store Name:', 'wpsl' ); ?></label>
36
+ <input id="wpsl-store-name" name="wpsl[store]" type="text" class="textinput <?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['store'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['store'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['store'] ) ); } else { echo esc_attr( stripslashes( $store_details['store'] ) ); } ?>" />
37
  </p>
38
  <p>
39
+ <label for="wpsl-store-address"><?php _e( 'Address:', 'wpsl' ); ?></label>
40
+ <input id="wpsl-store-address" name="wpsl[address]" type="text" class="textinput <?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['address'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['address'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['address'] ) ); } else { echo esc_attr( stripslashes( $store_details['address'] ) ); } ?>" />
41
+ </p>
42
+ <p>
43
+ <label for="wpsl-store-address2"><?php _e( 'Address 2:', 'wpsl' ); ?></label>
44
+ <input id="wpsl-store-address2" name="wpsl[address2]" type="text" class="textinput" value="<?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['address2'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['address2'] ) ); } else { echo esc_attr( stripslashes( $store_details['address2'] ) ); } ?>" />
45
  </p>
46
  <p>
47
  <label for="wpsl-store-city"><?php _e( 'City:', 'wpsl' ); ?></label>
48
+ <input id="wpsl-store-city" name="wpsl[city]" type="text" class="textinput <?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['city'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['city'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['city'] ) ); } else { echo esc_attr( stripslashes( $store_details['city'] ) ); } ?>" />
49
  </p>
50
  <p>
51
  <label for="wpsl-store-state"><?php _e( 'State / Province:', 'wpsl' ); ?></label>
52
+ <input id="wpsl-store-state" name="wpsl[state]" type="text" class="textinput" value="<?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['state'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['state'] ) ); } else { echo esc_attr( stripslashes( $store_details['state'] ) ); } ?>" />
53
  </p>
54
  <p>
55
  <label for="wpsl-store-zip"><?php _e( 'Zip Code:', 'wpsl' ); ?></label>
56
+ <input id="wpsl-store-zip" name="wpsl[zip]" type="text" class="textinput <?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['zip'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['zip'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['zip'] ) ); } else { echo esc_attr( stripslashes( $store_details['zip'] ) ); } ?>" />
57
  </p>
58
  <p>
59
  <label for="wpsl-store-country"><?php _e( 'Country:', 'wpsl' ); ?></label>
60
+ <input id="wpsl-store-country" name="wpsl[country]" type="text" class="textinput <?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['country'] ) ) { echo 'wpsl-error'; } ?>" value="<?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['country'] ) ) { echo esc_attr( stripslashes( $_POST['wpsl']['country'] ) ); } else { echo esc_attr( stripslashes( $store_details['country'] ) ); } ?>" />
61
  <input id="wpsl-country-iso" type="hidden" name="wpsl[country-iso]" value="<?php echo esc_attr( $store_details['country_iso'] ); ?>" />
62
  </p>
63
  <p>
64
  <label for="wpsl-store-lat"><?php _e( 'Latitude:', 'wpsl' ); ?></label>
65
+ <input id="wpsl-store-lat" name="wpsl[lat]" type="text" class="textinput" value="<?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['lat'] ) ) { echo esc_attr( $_POST['wpsl']['lat'] ); } else { echo esc_attr( $store_details['lat'] ); } ?>" />
66
  </p>
67
  <p>
68
  <label for="wpsl-store-lng"><?php _e( 'Longitude:', 'wpsl' ); ?></label>
69
+ <input id="wpsl-store-lng" name="wpsl[lng]" type="text" class="textinput" value="<?php if ( isset( $_POST['wpsl'] ) && empty( $_POST['wpsl']['lng'] ) ) { echo esc_attr( $_POST['wpsl']['lng'] ); } else { echo esc_attr( $store_details['lng'] ); } ?>" />
70
  </p>
71
  <p class="wpsl-submit-wrap">
72
  <input id="wpsl-lookup-location" type="submit" name="wpsl-lookup-location" class="button-primary" value="<?php _e( 'Preview location on the map', 'wpsl' ); ?>" />
85
  <div class="inside">
86
  <p>
87
  <label for="wpsl-store-phone"><?php _e( 'Phone:', 'wpsl' ); ?></label>
88
+ <input id="wpsl-store-phone" name="wpsl[phone]" type="text" class="textinput" value="<?php if ( isset( $_POST['wpsl']['phone'] ) ) { echo esc_attr( $_POST['wpsl']['phone'] ); } else { echo esc_attr( $store_details['phone'] ); } ?>">
89
  </p>
90
  <p>
91
  <label for="wpsl-store-fax"><?php _e( 'Fax:', 'wpsl' ); ?></label>
92
+ <input id="wpsl-store-fax" name="wpsl[fax]" type="text" class="textinput" value="<?php if ( isset( $_POST['wpsl']['fax'] ) ) { echo esc_attr( $_POST['wpsl']['fax'] ); } else { echo esc_attr( $store_details['fax'] ); } ?>">
93
  </p>
94
  <p>
95
  <label for="wpsl-store-email"><?php _e( 'Email:', 'wpsl' ); ?></label>
96
+ <input id="wpsl-store-email" name="wpsl[email]" type="email" class="textinput" value="<?php if ( isset( $_POST['wpsl']['email'] ) ) { echo esc_attr( $_POST['wpsl']['email'] ); } else { echo esc_attr( $store_details['email'] ); } ?>">
97
  </p>
98
  <p>
99
  <label for="wpsl-store-url"><?php _e( 'Url:', 'wpsl' ); ?></label>
100
+ <input id="wpsl-store-url" name="wpsl[url]" type="url" class="textinput" value="<?php if ( isset( $_POST['wpsl']['url'] ) ) { echo esc_url( $_POST['wpsl']['url'] ); } else { echo esc_url( $store_details['url'] ); } ?>">
101
  </p>
102
  <p>
103
  <label for="wpsl-store-desc"><?php _e( 'Description:', 'wpsl' ); ?></label>
104
+ <textarea id="wpsl-store-desc" name="wpsl[desc]" cols="5" rows="5"><?php if ( isset( $_POST['wpsl']['desc'] ) ) { echo esc_textarea( stripslashes( $_POST['wpsl']['desc'] ) ); } else { echo esc_textarea( stripslashes( $store_details['description'] ) ); } ?></textarea>
105
  </p>
106
  <p>
107
  <label for="wpsl-store-hours"><?php _e( 'Operation Hours:', 'wpsl' ); ?></label>
108
+ <textarea id="wpsl-store-hours" name="wpsl[hours]" cols="5" rows="5"><?php if ( isset( $_POST['wpsl']['hours'] ) ) { echo esc_textarea( stripslashes( $_POST['wpsl']['hours'] ) ); } else { echo esc_textarea( stripslashes( $store_details['hours'] ) ); } ?></textarea>
109
  </p>
110
+ <?php if ( current_user_can( 'upload_files' ) ) { ?>
111
  <div id="wpsl-thumb-wrap">
112
  <p>
113
  <label><?php _e( 'Thumbnail:', 'wpsl' ); ?></label>
127
  <input type="hidden" id="wpsl-thumb-id" name="wpsl[thumb-id]" value="<?php echo esc_attr( $store_details['thumb_id'] ); ?>" />
128
  </div>
129
  </div>
130
+ <?php } ?>
131
  </div>
132
  </div>
133
 
134
  <p>
135
  <input id="wpsl-update-store" type="submit" name="wpsl-update-store" class="button-primary" value="<?php _e( 'Update Store', 'wpsl' ); ?>" />
 
136
  </p>
137
  </div>
138
  </form>
admin/templates/faq.php CHANGED
@@ -3,16 +3,36 @@
3
 
4
  <div id="wpsl-faq">
5
  <dl>
6
- <dt>How do I show the store locator on my page?</dt>
7
- <dd>Add this shortcode <code>[wpsl]</code> to the page where you want to show the store locator.</dd>
 
 
8
  </dl>
9
  <dl>
10
- <dt>The map doesn't display properly. It's either broken in half or doesn't load at all.</dt>
11
- <dd>Make sure you have defined a start point for the map under settings -> map settings.</dd>
 
 
12
  </dl>
13
  <dl>
14
- <dt>I get an error saying the 'sensor' parameter specified in the request must be set to either 'true' or 'false'.</dt>
15
- <dd>Make sure you don't have any security plugins, or custom functions running that strip away version numbers from file paths.</dd>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  </dl>
17
  </div>
18
  </div>
3
 
4
  <div id="wpsl-faq">
5
  <dl>
6
+ <dt><?php _e( 'How do I show the store locator on my page?', 'wpsl' ); ?></dt>
7
+ <dd>
8
+ <p><?php _e( 'Add this shortcode <code>[wpsl]</code> to the page where you want to show the store locator.', 'wpsl' ); ?></p>
9
+ </dd>
10
  </dl>
11
  <dl>
12
+ <dt><?php _e( 'The map doesn\'t display properly. It\'s either broken in half or doesn\'t load at all.', 'wpsl'); ?></dt>
13
+ <dd>
14
+ <p><?php _e( 'Make sure you have defined a start point for the map under settings -> map settings.', 'wpsl'); ?></p>
15
+ </dd>
16
  </dl>
17
  <dl>
18
+ <dt><?php _e( 'I get an error saying the "sensor" parameter specified in the request must be set to either "true" or "false".', 'wpsl'); ?></dt>
19
+ <dd>
20
+ <p><?php _e( 'Make sure you don\'t have any security plugins, or custom functions running that strip away version numbers from file paths.', 'wpsl'); ?></p>
21
+ </dd>
22
+ </dl>
23
+ <dl>
24
+ <dt><?php _e( 'The store locator doesn\'t load, it only shows the number 1?', 'wpsl' ); ?></dt>
25
+ <dd>
26
+ <p><?php _e( 'This is most likely caused by your theme using ajax navigation ( the loading of content without reloading the page ), or a conflict with another plugin. Try to disable the ajax navigation in the theme settings, or deactivate the plugin that enables it to see if that solves the problem.', 'wpsl' ); ?></p>
27
+ <p><?php _e( 'If you don\'t use ajax navigation, but do see the number 1 it\'s probably a conflict with another plugin. Try to disable the plugins one by one to see if one of them is causing a conflict.', 'wpsl' ); ?></p>
28
+ <p><?php echo sprintf( __( 'If you find a plugin or theme that causes a conflict, please report it on the <a href="%s">support page</a>.', 'wpsl' ), 'http://wordpress.org/support/plugin/wp-store-locator' ); ?></p>
29
+ </dd>
30
+ </dl>
31
+ <dl>
32
+ <dt><?php _e( 'Why does it show the location I searched for in the wrong country?', 'wpsl' ); ?></dt>
33
+ <dd>
34
+ <p><?php _e( 'Some location names exist in more then one country, and Google will guess which one you mean. This can be fixed by setting the correct "Map Region" on the settings page -> "API Settings".', 'wpsl' ); ?></p>
35
+ </dd>
36
  </dl>
37
  </div>
38
  </div>
admin/templates/map-settings.php CHANGED
@@ -1,14 +1,13 @@
1
  <div id="wpsl-wrap" class="wrap wpsl-settings">
2
  <h2>WP Store Locator: <?php _e( 'Settings', 'wpsl' ); ?></h2>
3
 
4
- <?php global $wpdb; ?>
 
5
 
6
- <?php settings_errors(); ?>
7
- <ul id="wpsl-mainnav" class="nav-tab-wrapper">
8
- <li><a class="nav-tab" href="<?php echo admin_url( 'admin.php?page=wpsl_store_editor' ); ?>"><?php _e( 'Current Stores', 'wpsl' ); ?></a></li>
9
- <li><a class="nav-tab" href="<?php echo admin_url( 'admin.php?page=wpsl_add_store' ); ?>"><?php _e( 'Add Store', 'wpsl' ); ?></a></li>
10
- <li><a class="nav-tab nav-tab-active" href="<?php echo admin_url( 'admin.php?page=wpsl_settings' ); ?>"><?php _e( 'Settings', 'wpsl' ); ?></a></li>
11
- </ul>
12
 
13
  <form id="wpsl-settings-form" method="post" action="options.php" accept-charset="utf-8">
14
  <div class="postbox-container">
@@ -23,20 +22,16 @@
23
  <p>
24
  <label for="wpsl-api-language"><?php _e( 'Map language:', 'wpsl' ); ?></label>
25
  <select id="wpsl-api-language" name="wpsl_api[language]">
26
- <?php
27
- echo $this->get_api_option_list( 'language' );
28
- ?>
29
  </select>
30
  </p>
31
  <p>
32
  <label for="wpsl-api-region"><?php _e( 'Map region:', 'wpsl' ); ?></label>
33
  <select id="wpsl-api-region" name="wpsl_api[region]">
34
- <?php
35
- echo $this->get_api_option_list( 'region' );
36
- ?>
37
  </select>
38
  </p>
39
- <em><?php _e( '* A valid <a href="https://developers.google.com/maps/documentation/javascript/tutorial#api_key">API key</a> allows you to monitor the API usage <br> and is required if you need to purchase additional quota.', 'wpsl' ); ?></em>
40
  </div>
41
  </div>
42
  </div>
@@ -61,7 +56,7 @@
61
  </p>
62
  <p>
63
  <label for="wpsl-bounce"><?php _e( 'If a user hovers over the search results, the corresponding marker will bounce?', 'wpsl' ); ?></label>
64
- <input type="checkbox" value="" <?php checked( $this->settings['marker_bounce'] == '1', true ); ?> name="wpsl_map[marker_bounce]" id="wpsl-bounce">
65
  </p>
66
  <em><?php _e( '* The default value is set between the ( )', 'wpsl' ); ?></em>
67
  </div>
@@ -76,11 +71,11 @@
76
  <div class="inside">
77
  <p>
78
  <label for="wpsl-auto-locate"><?php _e( 'Attempt to auto-locate the user:', 'wpsl' ); ?></label>
79
- <input type="checkbox" value="" <?php checked( $this->settings['auto_locate'] == '1', true ); ?> name="wpsl_map[auto_locate]" id="wpsl-auto-locate">
80
  </p>
81
  <p>
82
  <label for="wpsl-auto-load"><?php _e( 'Load all stores on page load:', 'wpsl' ); ?></label>
83
- <input type="checkbox" value="" <?php checked( $this->settings['auto_load'] == '1', true ); ?> name="wpsl_map[auto_load]" id="wpsl-auto-locate">
84
  </p>
85
  <p>
86
  <label for="wpsl-zoom-name"><?php _e( 'Start point: *', 'wpsl' ); ?></label>
@@ -97,11 +92,11 @@
97
  </p>
98
  <p>
99
  <label for="wpsl-streetview"><?php _e( 'Show the street view controls?', 'wpsl' ); ?></label>
100
- <input type="checkbox" value="" <?php checked( $this->settings['streetview'] == '1', true ); ?> name="wpsl_map[streetview]" id="wpsl-streetview">
101
  </p>
102
  <p>
103
  <label for="wpsl-pan-controls"><?php _e( 'Show the pan controls?', 'wpsl' ); ?></label>
104
- <input type="checkbox" value="" <?php checked( $this->settings['pan_controls'] == '1', true ); ?> name="wpsl_map[pan_controls]" id="wpsl-pan-controls">
105
  </p>
106
  <p>
107
  <label><?php _e( 'Position of the map controls:', 'wpsl' ); ?></label>
@@ -148,41 +143,57 @@
148
  <label for="wpsl-label-width"><?php _e( 'Search and radius label width *', 'wpsl' ); ?></label>
149
  <input size="3" value="<?php echo esc_attr( $this->settings['label_width'] ); ?>" id="wpsl-label-width" name="wpsl_design[label_width]"> px
150
  </p>
 
 
 
 
 
 
 
 
151
  <p>
152
  <label for="wpsl-design-results"><?php _e( 'Show the limit results dropdown?', 'wpsl' ); ?></label>
153
- <input type="checkbox" value="" <?php checked( $this->settings['results_dropdown'] == '1', true ); ?> name="wpsl_design[design_results]">
154
  </p>
155
  <p>
156
  <label for="wpsl-new-window"><?php _e( 'Open links in a new window?', 'wpsl' ); ?></label>
157
- <input type="checkbox" value="" <?php checked( $this->settings['new_window'] == '1', true ); ?> name="wpsl_design[new_window]" id="wpsl-new-window">
158
  </p>
159
  <p>
160
  <label for="wpsl-reset-map"><?php _e( 'Show a reset map button?', 'wpsl' ); ?></label>
161
- <input type="checkbox" value="" <?php checked( $this->settings['reset_map'] == '1', true ); ?> name="wpsl_design[reset_map]" id="wpsl-reset-map">
162
  </p>
163
- <p>
164
- <label for="wpsl-store-below"><?php _e( 'Show the store listings below the map?', 'wpsl' ); ?></label>
165
- <input type="checkbox" value="" <?php checked( $this->settings['store_below'] == '1', true ); ?> name="wpsl_design[store_below]" id="wpsl-store-below">
166
- </p>
167
- <p id="wpsl-store-below-scroll" <?php if ( $this->settings['store_below'] == '0' ) { echo 'style="display:none;"'; } ?>>
168
- <label for="wpsl-more-info-list"><?php _e( 'Hide the scrollbar?', 'wpsl' ); ?></label>
169
- <input type="checkbox" value="" <?php checked( $this->settings['store_below_scroll'] == '1', true ); ?> name="wpsl_design[store_below_scroll]" id="wpsl-store-below-scroll">
170
- </p>
171
  <p>
172
  <label for="wpsl-direction-redirect"><?php _e( 'When a user clicks on "Directions", open a new window and show the route on maps.google.com', 'wpsl' ); ?></label>
173
- <input type="checkbox" value="" <?php checked( $this->settings['direction_redirect'] == '1', true ); ?> name="wpsl_design[direction_redirect]" id="wpsl-direction-redirect">
174
  </p>
175
  <p>
176
  <label for="wpsl-more-info"><?php _e( 'Show a "More info" link in the store listings?', 'wpsl' ); ?></label>
177
- <input type="checkbox" value="" <?php checked( $this->settings['more_info'] == '1', true ); ?> name="wpsl_design[more_info]" id="wpsl-more-info">
178
- </p>
179
  <p id="wpsl-more-info-options" <?php if ( $this->settings['more_info'] == '0' ) { echo 'style="display:none;"'; } ?>>
180
  <label for="wpsl-more-info-list"><?php _e( 'Where do you want to show the "More info" details?', 'wpsl' ); ?></label>
181
  <?php echo $this->show_more_info_options(); ?>
182
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  <p>
184
  <label for="wpsl-mouse-focus"><?php _e( 'On pageload move the mousecursor to the input field. **', 'wpsl' ); ?></label>
185
- <input type="checkbox" value="" <?php checked( $this->settings['mouse_focus'] == '1', true ); ?> name="wpsl_design[mouse_focus]" id="wpsl-mouse-focus">
186
  </p>
187
  <em><?php _e( '* This is the text that is placed before the search input and radius dropdown', 'wpsl' ); ?></em>
188
  <em><?php _e( '** If the store locator is not placed at the top of the page, enabling this feature can result in the page sliding down.', 'wpsl' ); ?></em>
@@ -197,6 +208,33 @@
197
  <h3><span><?php _e( 'Markers', 'wpsl' ); ?></span></h3>
198
  <div class="inside">
199
  <?php echo $this->show_marker_options(); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  </div>
201
  </div>
202
  </div>
@@ -255,6 +293,10 @@
255
  <label for="wpsl-directions"><?php _e( 'Get directions:', 'wpsl' ); ?></label>
256
  <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['directions_label'] ) ); ?>" name="wpsl_label[directions]" class="textinput" id="wpsl-directions">
257
  </p>
 
 
 
 
258
  <p>
259
  <label for="wpsl-back"><?php _e( 'Back:', 'wpsl' ); ?></label>
260
  <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['back_label'] ) ); ?>" name="wpsl_label[back]" class="textinput" id="wpsl-back">
@@ -262,7 +304,15 @@
262
  <p>
263
  <label for="wpsl-reset"><?php _e( 'Reset:', 'wpsl' ); ?></label>
264
  <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['reset_label'] ) ); ?>" name="wpsl_label[reset]" class="textinput" id="wpsl-reset">
265
- </p>
 
 
 
 
 
 
 
 
266
  <p>
267
  <label for="wpsl-error"><?php _e( 'General error:', 'wpsl' ); ?></label>
268
  <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['error_label'] ) ); ?>" name="wpsl_label[error]" class="textinput" id="wpsl-error">
@@ -271,7 +321,7 @@
271
  <label for="wpsl-limit"><?php _e( 'Query limit error:', 'wpsl' ); ?> *</label>
272
  <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['limit_label'] ) ); ?>" name="wpsl_label[limit]" class="textinput" id="wpsl-limit">
273
  </p>
274
- <em><?php _e( '* You can raise the <a href="https://developers.google.com/maps/documentation/javascript/usage#usage_limits">usage limit</a> by obtaining an API <a href="https://developers.google.com/maps/documentation/javascript/tutorial#api_key">key</a>, <br> and fill in the "API key" field at the top of this page.', 'wpsl' ); ?></em>
275
  </div>
276
  </div>
277
  </div>
1
  <div id="wpsl-wrap" class="wrap wpsl-settings">
2
  <h2>WP Store Locator: <?php _e( 'Settings', 'wpsl' ); ?></h2>
3
 
4
+ <?php
5
+ global $wpdb;
6
 
7
+ settings_errors();
8
+
9
+ echo $this->create_menu();
10
+ ?>
 
 
11
 
12
  <form id="wpsl-settings-form" method="post" action="options.php" accept-charset="utf-8">
13
  <div class="postbox-container">
22
  <p>
23
  <label for="wpsl-api-language"><?php _e( 'Map language:', 'wpsl' ); ?></label>
24
  <select id="wpsl-api-language" name="wpsl_api[language]">
25
+ <?php echo $this->get_api_option_list( 'language' ); ?>
 
 
26
  </select>
27
  </p>
28
  <p>
29
  <label for="wpsl-api-region"><?php _e( 'Map region:', 'wpsl' ); ?></label>
30
  <select id="wpsl-api-region" name="wpsl_api[region]">
31
+ <?php echo $this->get_api_option_list( 'region' ); ?>
 
 
32
  </select>
33
  </p>
34
+ <em><?php echo sprintf( __( '* A valid <a href="%s">API key</a> allows you to monitor the API usage <br> and is required if you need to purchase additional quota.', 'wpsl' ), 'https://developers.google.com/maps/documentation/javascript/tutorial#api_key' ); ?></em>
35
  </div>
36
  </div>
37
  </div>
56
  </p>
57
  <p>
58
  <label for="wpsl-bounce"><?php _e( 'If a user hovers over the search results, the corresponding marker will bounce?', 'wpsl' ); ?></label>
59
+ <input type="checkbox" value="" <?php checked( $this->settings['marker_bounce'], true ); ?> name="wpsl_map[marker_bounce]" id="wpsl-bounce">
60
  </p>
61
  <em><?php _e( '* The default value is set between the ( )', 'wpsl' ); ?></em>
62
  </div>
71
  <div class="inside">
72
  <p>
73
  <label for="wpsl-auto-locate"><?php _e( 'Attempt to auto-locate the user:', 'wpsl' ); ?></label>
74
+ <input type="checkbox" value="" <?php checked( $this->settings['auto_locate'], true ); ?> name="wpsl_map[auto_locate]" id="wpsl-auto-locate">
75
  </p>
76
  <p>
77
  <label for="wpsl-auto-load"><?php _e( 'Load all stores on page load:', 'wpsl' ); ?></label>
78
+ <input type="checkbox" value="" <?php checked( $this->settings['auto_load'], true ); ?> name="wpsl_map[auto_load]" id="wpsl-auto-locate">
79
  </p>
80
  <p>
81
  <label for="wpsl-zoom-name"><?php _e( 'Start point: *', 'wpsl' ); ?></label>
92
  </p>
93
  <p>
94
  <label for="wpsl-streetview"><?php _e( 'Show the street view controls?', 'wpsl' ); ?></label>
95
+ <input type="checkbox" value="" <?php checked( $this->settings['streetview'], true ); ?> name="wpsl_map[streetview]" id="wpsl-streetview">
96
  </p>
97
  <p>
98
  <label for="wpsl-pan-controls"><?php _e( 'Show the pan controls?', 'wpsl' ); ?></label>
99
+ <input type="checkbox" value="" <?php checked( $this->settings['pan_controls'], true ); ?> name="wpsl_map[pan_controls]" id="wpsl-pan-controls">
100
  </p>
101
  <p>
102
  <label><?php _e( 'Position of the map controls:', 'wpsl' ); ?></label>
143
  <label for="wpsl-label-width"><?php _e( 'Search and radius label width *', 'wpsl' ); ?></label>
144
  <input size="3" value="<?php echo esc_attr( $this->settings['label_width'] ); ?>" id="wpsl-label-width" name="wpsl_design[label_width]"> px
145
  </p>
146
+ <p>
147
+ <label for="wpsl-store-template"><?php _e( 'Select template', 'wpsl' ); ?></label>
148
+ <?php echo $this->show_template_options(); ?>
149
+ </p>
150
+ <p id="wpsl-store-below-scroll" <?php if ( $this->settings['template_id'] != '1' ) { echo 'style="display:none;"'; } ?>>
151
+ <label for="wpsl-more-info-list"><?php _e( 'Hide the scrollbar?', 'wpsl' ); ?></label>
152
+ <input type="checkbox" value="" <?php checked( $this->settings['store_below_scroll'], true ); ?> name="wpsl_design[store_below_scroll]" id="wpsl-store-below-scroll">
153
+ </p>
154
  <p>
155
  <label for="wpsl-design-results"><?php _e( 'Show the limit results dropdown?', 'wpsl' ); ?></label>
156
+ <input type="checkbox" value="" <?php checked( $this->settings['results_dropdown'], true ); ?> name="wpsl_design[design_results]">
157
  </p>
158
  <p>
159
  <label for="wpsl-new-window"><?php _e( 'Open links in a new window?', 'wpsl' ); ?></label>
160
+ <input type="checkbox" value="" <?php checked( $this->settings['new_window'], true ); ?> name="wpsl_design[new_window]" id="wpsl-new-window">
161
  </p>
162
  <p>
163
  <label for="wpsl-reset-map"><?php _e( 'Show a reset map button?', 'wpsl' ); ?></label>
164
+ <input type="checkbox" value="" <?php checked( $this->settings['reset_map'], true ); ?> name="wpsl_design[reset_map]" id="wpsl-reset-map">
165
  </p>
 
 
 
 
 
 
 
 
166
  <p>
167
  <label for="wpsl-direction-redirect"><?php _e( 'When a user clicks on "Directions", open a new window and show the route on maps.google.com', 'wpsl' ); ?></label>
168
+ <input type="checkbox" value="" <?php checked( $this->settings['direction_redirect'], true ); ?> name="wpsl_design[direction_redirect]" id="wpsl-direction-redirect">
169
  </p>
170
  <p>
171
  <label for="wpsl-more-info"><?php _e( 'Show a "More info" link in the store listings?', 'wpsl' ); ?></label>
172
+ <input type="checkbox" value="" <?php checked( $this->settings['more_info'], true ); ?> name="wpsl_design[more_info]" id="wpsl-more-info">
173
+ </p>
174
  <p id="wpsl-more-info-options" <?php if ( $this->settings['more_info'] == '0' ) { echo 'style="display:none;"'; } ?>>
175
  <label for="wpsl-more-info-list"><?php _e( 'Where do you want to show the "More info" details?', 'wpsl' ); ?></label>
176
  <?php echo $this->show_more_info_options(); ?>
177
  </p>
178
+ <p>
179
+ <label for="wpsl-store-url"><?php _e( 'If a store url exists, make the store name clickable?', 'wpsl' ); ?></label>
180
+ <input type="checkbox" value="" <?php checked( $this->settings['store_url'], true ); ?> name="wpsl_design[store_url]" id="wpsl-store-url">
181
+ </p>
182
+ <p>
183
+ <label for="wpsl-phone-url"><?php _e( 'Make the phone number clickable on mobile devices?', 'wpsl' ); ?></label>
184
+ <input type="checkbox" value="" <?php checked( $this->settings['phone_url'], true ); ?> name="wpsl_design[phone_url]" id="wpsl-phone-url">
185
+ </p>
186
+ <p>
187
+ <label for="wpsl-marker-streetview"><?php _e( 'If available for the current location, show a link to enable street view from the infowindow?', 'wpsl' ); ?></label>
188
+ <input type="checkbox" value="" <?php checked( $this->settings['marker_streetview'], true ); ?> name="wpsl_design[marker_streetview]" id="wpsl-marker-streetview">
189
+ </p>
190
+ <p>
191
+ <label for="wpsl-marker-zoom-to"><?php _e( 'Show a "zoom to" link in the infowindow?', 'wpsl' ); ?></label>
192
+ <input type="checkbox" value="" <?php checked( $this->settings['marker_zoom_to'], true ); ?> name="wpsl_design[marker_zoom_to]" id="wpsl-marker-zoom-to">
193
+ </p>
194
  <p>
195
  <label for="wpsl-mouse-focus"><?php _e( 'On pageload move the mousecursor to the input field. **', 'wpsl' ); ?></label>
196
+ <input type="checkbox" value="" <?php checked( $this->settings['mouse_focus'], true ); ?> name="wpsl_design[mouse_focus]" id="wpsl-mouse-focus">
197
  </p>
198
  <em><?php _e( '* This is the text that is placed before the search input and radius dropdown', 'wpsl' ); ?></em>
199
  <em><?php _e( '** If the store locator is not placed at the top of the page, enabling this feature can result in the page sliding down.', 'wpsl' ); ?></em>
208
  <h3><span><?php _e( 'Markers', 'wpsl' ); ?></span></h3>
209
  <div class="inside">
210
  <?php echo $this->show_marker_options(); ?>
211
+ <p>
212
+ <label for="wpsl-marker-clusters"><?php _e( 'Enable marker clusters? *', 'wpsl' ); ?></label>
213
+ <input type="checkbox" value="" <?php checked( $this->settings['marker_clusters'], true ); ?> name="wpsl_map[marker_clusters]" id="wpsl-marker-clusters">
214
+ </p>
215
+ <p class="wpsl-cluster-options" <?php if ( !$this->settings['marker_clusters'] ) { echo 'style="display:none;"'; } ?>>
216
+ <label for="wpsl-marker-zoom"><?php _e( 'Max zoom level:', 'wpsl' ); ?></label>
217
+ <?php echo $this->show_cluster_options( 'cluster_zoom' ); ?>
218
+ </p>
219
+ <p class="wpsl-cluster-options" <?php if ( !$this->settings['marker_clusters'] ) { echo 'style="display:none;"'; } ?>>
220
+ <label for="wpsl-marker-cluster-size"><?php _e( 'Cluster size:', 'wpsl' ); ?></label>
221
+ <?php echo $this->show_cluster_options( 'cluster_size' ); ?>
222
+ </p>
223
+ <em><?php _e( '* Recommended for maps with a large amounts of markers.', 'wpsl' ); ?></em>
224
+ </div>
225
+ </div>
226
+ </div>
227
+ </div>
228
+
229
+ <div class="postbox-container">
230
+ <div class="metabox-holder">
231
+ <div class="postbox">
232
+ <h3><span><?php _e( 'Store Editor Settings', 'wpsl' ); ?></span></h3>
233
+ <div class="inside">
234
+ <p>
235
+ <label for="wpsl-editor-country"><?php _e( 'Default country that will be used on the "Add Store" page.', 'wpsl' ); ?></label>
236
+ <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['editor_country'] ) ); ?>" name="wpsl_editor[default_country]" class="textinput" id="wpsl-editor-country">
237
+ </p>
238
  </div>
239
  </div>
240
  </div>
293
  <label for="wpsl-directions"><?php _e( 'Get directions:', 'wpsl' ); ?></label>
294
  <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['directions_label'] ) ); ?>" name="wpsl_label[directions]" class="textinput" id="wpsl-directions">
295
  </p>
296
+ <p>
297
+ <label for="wpsl-no-directions"><?php _e( 'No directions found:', 'wpsl' ); ?></label>
298
+ <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['no_directions_label'] ) ); ?>" name="wpsl_label[no_directions]" class="textinput" id="wpsl-no-directions">
299
+ </p>
300
  <p>
301
  <label for="wpsl-back"><?php _e( 'Back:', 'wpsl' ); ?></label>
302
  <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['back_label'] ) ); ?>" name="wpsl_label[back]" class="textinput" id="wpsl-back">
304
  <p>
305
  <label for="wpsl-reset"><?php _e( 'Reset:', 'wpsl' ); ?></label>
306
  <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['reset_label'] ) ); ?>" name="wpsl_label[reset]" class="textinput" id="wpsl-reset">
307
+ </p>
308
+ <p>
309
+ <label for="wpsl-street-view"><?php _e( 'Street view:', 'wpsl' ); ?></label>
310
+ <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['street_view_label'] ) ); ?>" name="wpsl_label[street_view]" class="textinput" id="wpsl-street-view">
311
+ </p>
312
+ <p>
313
+ <label for="wpsl-zoom-here"><?php _e( 'Zoom here:', 'wpsl' ); ?></label>
314
+ <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['zoom_here_label'] ) ); ?>" name="wpsl_label[zoom_here]" class="textinput" id="wpsl-zoom-here">
315
+ </p>
316
  <p>
317
  <label for="wpsl-error"><?php _e( 'General error:', 'wpsl' ); ?></label>
318
  <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['error_label'] ) ); ?>" name="wpsl_label[error]" class="textinput" id="wpsl-error">
321
  <label for="wpsl-limit"><?php _e( 'Query limit error:', 'wpsl' ); ?> *</label>
322
  <input type="text" value="<?php echo esc_attr( stripslashes( $this->settings['limit_label'] ) ); ?>" name="wpsl_label[limit]" class="textinput" id="wpsl-limit">
323
  </p>
324
+ <em><?php echo sprintf( __( '* You can raise the <a href="%s">usage limit</a> by obtaining an API <a href="%s">key</a>, <br> and fill in the "API key" field at the top of this page.', 'wpsl' ), 'https://developers.google.com/maps/documentation/javascript/usage#usage_limits', 'https://developers.google.com/maps/documentation/javascript/tutorial#api_key' ); ?></em>
325
  </div>
326
  </div>
327
  </div>
admin/templates/stores-overview.php CHANGED
@@ -9,11 +9,7 @@ $store_overview->prepare_items();
9
  <h2>WP Store Locator</h2>
10
  <?php settings_errors(); ?>
11
 
12
- <ul id="wpsl-mainnav">
13
- <li><a class="nav-tab nav-tab-active" href="<?php echo admin_url( 'admin.php?page=wpsl_store_editor' ); ?>"><?php _e( 'Current Stores', 'wpsl' ); ?></a></li>
14
- <li><a class="nav-tab" href="<?php echo admin_url( 'admin.php?page=wpsl_add_store' ); ?>"><?php _e( 'Add Store', 'wpsl' ); ?></a></li>
15
- <li><a class="nav-tab" href="<?php echo admin_url( 'admin.php?page=wpsl_settings' ); ?>"><?php _e( 'Settings', 'wpsl' ); ?></a></li>
16
- </ul>
17
 
18
  <form method="post">
19
  <?php
9
  <h2>WP Store Locator</h2>
10
  <?php settings_errors(); ?>
11
 
12
+ <?php echo $this->create_menu(); ?>
 
 
 
 
13
 
14
  <form method="post">
15
  <?php
css/styles.css CHANGED
@@ -306,8 +306,18 @@ div elements, we disable it to prevent it from messing up the map
306
  .wpsl-store-hours strong {
307
  display:block;
308
  }
309
- .wpsl-info-window .wpsl-directions {
310
- margin:10px 0;
 
 
 
 
 
 
 
 
 
 
311
  }
312
 
313
  /* --- EASYDROPDOWN DEFAULT THEME --- */
@@ -501,7 +511,6 @@ wpsl-search-input.focus,
501
  }
502
 
503
  /* .focus class is also added on hover */
504
-
505
  .wpsl-dropdown li.focus{
506
  background: #f8f9f8;
507
  position: relative;
@@ -531,6 +540,8 @@ wpsl-search-input.focus,
531
  margin-bottom:10px;
532
  }
533
 
 
 
534
  @media (max-width: 825px) {
535
  #wpsl-search-input {
536
  width: 348px;
306
  .wpsl-store-hours strong {
307
  display:block;
308
  }
309
+
310
+ .wpsl-info-actions {
311
+ display:block;
312
+ margin:10px 0;
313
+ }
314
+ .wpsl-info-actions a {
315
+ float:left;
316
+ margin-right: 7px;
317
+ }
318
+
319
+ .wpsl-zoom-here {
320
+ margin-right:0;
321
  }
322
 
323
  /* --- EASYDROPDOWN DEFAULT THEME --- */
511
  }
512
 
513
  /* .focus class is also added on hover */
 
514
  .wpsl-dropdown li.focus{
515
  background: #f8f9f8;
516
  position: relative;
540
  margin-bottom:10px;
541
  }
542
 
543
+ /* */
544
+
545
  @media (max-width: 825px) {
546
  #wpsl-search-input {
547
  width: 348px;
frontend/class-frontend.php CHANGED
@@ -13,10 +13,10 @@ if ( ! defined( 'ABSPATH' ) ) exit;
13
 
14
  if ( !class_exists( 'WPSL_Frontend' ) ) {
15
  /**
16
- * Handle the frontend of the store locator
17
- *
18
- * @since 1.0
19
- */
20
  class WPSL_Frontend extends WP_Store_locator {
21
 
22
  /**
@@ -33,15 +33,12 @@ if ( !class_exists( 'WPSL_Frontend' ) ) {
33
  * @since 1.0
34
  * @return void
35
  */
36
- public function render_store_locator() {
37
-
38
- if ( $this->settings['store_below'] ) {
39
- $output = require_once( WPSL_PLUGIN_DIR . 'frontend/templates/store-listings-below.php' );
40
- } else {
41
- $output = require_once( WPSL_PLUGIN_DIR . 'frontend/templates/default.php' );
42
- }
43
-
44
  $this->add_frontend_scripts();
 
 
 
45
 
46
  return $output;
47
  }
@@ -55,7 +52,7 @@ if ( !class_exists( 'WPSL_Frontend' ) ) {
55
  public function get_custom_css() {
56
  $css = '<style>' . "\r\n";
57
 
58
- if ( ( $this->settings['store_below'] == '1' ) && ( $this->settings['store_below_scroll'] == '1' ) ) {
59
  $css .= "#wpsl-gmap {height:" . esc_attr( $this->settings['height'] ) . "px !important;}" . "\r\n";
60
  $css .= "#wpsl-stores, #wpsl-direction-details {height:auto !important;}";
61
  } else {
@@ -124,7 +121,7 @@ if ( !class_exists( 'WPSL_Frontend' ) ) {
124
  }
125
  }
126
 
127
- return $api_data;
128
  }
129
 
130
  /**
@@ -172,17 +169,23 @@ if ( !class_exists( 'WPSL_Frontend' ) ) {
172
  * @since 1.0
173
  * @return void
174
  */
175
- public function add_frontend_scripts( ) {
176
  wp_enqueue_style( 'wpsl-css', WPSL_URL . 'css/styles.css', false );
177
  wp_enqueue_script( 'wpsl-dropdown', WPSL_URL.'js/jquery.easydropdown.min.js', array( 'jquery' ) ); //not minified version is in the js folder
178
- wp_enqueue_script( 'wpsl-gmap', ( "//maps.google.com/maps/api/js?sensor=false".$this->get_gmap_api_attributes() ),'' ,'' ,true );
179
- wp_enqueue_script( 'wpsl-js', WPSL_URL.'js/wpsl-gmap.js', array( 'jquery' ) );
 
 
 
 
 
180
 
181
  $dropdown_defaults = $this->get_dropdown_defaults();
182
 
183
  $settings = array(
184
  'startMarker' => $this->create_retina_filename( $this->settings['start_marker'] ),
185
  'storeMarker' => $this->create_retina_filename( $this->settings['store_marker'] ),
 
186
  'autoLocate' => $this->settings['auto_locate'],
187
  'autoLoad' => $this->settings['auto_load'],
188
  'mapType' => $this->settings['map_type'],
@@ -197,28 +200,42 @@ if ( !class_exists( 'WPSL_Frontend' ) ) {
197
  'resetMap' => $this->settings['reset_map'],
198
  'directionRedirect' => $this->settings['direction_redirect'],
199
  'moreInfo' => $this->settings['more_info'],
 
 
200
  'moreInfoLocation' => $this->settings['more_info_location'],
201
  'mouseFocus' => $this->settings['mouse_focus'],
202
- 'storeBelow' => $this->settings['store_below'],
 
 
203
  'maxResults' => $dropdown_defaults['max_results'],
204
  'searchRadius' => $dropdown_defaults['search_radius'],
205
  'distanceUnit' => $this->settings['distance_unit'],
206
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
207
  'path' => WPSL_URL,
208
  );
209
-
 
 
 
 
 
 
 
210
  $labels = array(
211
- 'preloader' => stripslashes( $this->settings['preloader_label'] ),
212
- 'noResults' => stripslashes( $this->settings['no_results_label'] ),
213
- 'moreInfo' => stripslashes( $this->settings['more_label'] ),
214
- 'generalError' => stripslashes( $this->settings['error_label'] ),
215
- 'queryLimit' => stripslashes( $this->settings['limit_label'] ),
216
- 'directions' => stripslashes( $this->settings['directions_label'] ),
217
- 'phone' => stripslashes( $this->settings['phone_label'] ),
218
- 'fax' => stripslashes( $this->settings['fax_label'] ),
219
- 'hours' => stripslashes( $this->settings['hours_label'] ),
220
- 'startPoint' => stripslashes( $this->settings['start_label'] ),
221
- 'back' => stripslashes( $this->settings['back_label'] )
 
 
 
222
  );
223
 
224
  wp_localize_script( 'wpsl-js', 'wpslSettings', $settings );
13
 
14
  if ( !class_exists( 'WPSL_Frontend' ) ) {
15
  /**
16
+ * Handle the frontend of the store locator
17
+ *
18
+ * @since 1.0
19
+ */
20
  class WPSL_Frontend extends WP_Store_locator {
21
 
22
  /**
33
  * @since 1.0
34
  * @return void
35
  */
36
+ public function render_store_locator() {
37
+
 
 
 
 
 
 
38
  $this->add_frontend_scripts();
39
+
40
+ $template_list = $this->get_templates();
41
+ $output = require_once( $template_list[ absint( $this->settings['template_id'] ) ]['path'] );
42
 
43
  return $output;
44
  }
52
  public function get_custom_css() {
53
  $css = '<style>' . "\r\n";
54
 
55
+ if ( ( $this->settings['template_id'] == '1' ) && ( $this->settings['store_below_scroll'] == '1' ) ) {
56
  $css .= "#wpsl-gmap {height:" . esc_attr( $this->settings['height'] ) . "px !important;}" . "\r\n";
57
  $css .= "#wpsl-stores, #wpsl-direction-details {height:auto !important;}";
58
  } else {
121
  }
122
  }
123
 
124
+ return apply_filters( 'wpsl_gmap_api_attributes', $api_data );
125
  }
126
 
127
  /**
169
  * @since 1.0
170
  * @return void
171
  */
172
+ public function add_frontend_scripts() {
173
  wp_enqueue_style( 'wpsl-css', WPSL_URL . 'css/styles.css', false );
174
  wp_enqueue_script( 'wpsl-dropdown', WPSL_URL.'js/jquery.easydropdown.min.js', array( 'jquery' ) ); //not minified version is in the js folder
175
+ wp_enqueue_script( 'wpsl-gmap', ( "//maps.google.com/maps/api/js?sensor=false".$this->get_gmap_api_attributes() ),'' ,'' ,true );
176
+
177
+ if ( $this->settings['marker_clusters'] ) {
178
+ wp_enqueue_script( 'wpsl-cluster', WPSL_URL . 'js/markerclusterer.min.js' ); //not minified version is in the /js folder
179
+ }
180
+
181
+ wp_enqueue_script( 'wpsl-js', WPSL_URL.'js/wpsl-gmap.js', array( 'jquery' ) );
182
 
183
  $dropdown_defaults = $this->get_dropdown_defaults();
184
 
185
  $settings = array(
186
  'startMarker' => $this->create_retina_filename( $this->settings['start_marker'] ),
187
  'storeMarker' => $this->create_retina_filename( $this->settings['store_marker'] ),
188
+ 'markerClusters' => $this->settings['marker_clusters'],
189
  'autoLocate' => $this->settings['auto_locate'],
190
  'autoLoad' => $this->settings['auto_load'],
191
  'mapType' => $this->settings['map_type'],
200
  'resetMap' => $this->settings['reset_map'],
201
  'directionRedirect' => $this->settings['direction_redirect'],
202
  'moreInfo' => $this->settings['more_info'],
203
+ 'storeUrl' => $this->settings['store_url'],
204
+ 'phoneUrl' => $this->settings['phone_url'],
205
  'moreInfoLocation' => $this->settings['more_info_location'],
206
  'mouseFocus' => $this->settings['mouse_focus'],
207
+ 'templateId' => $this->settings['template_id'],
208
+ 'markerStreetView' => $this->settings['marker_streetview'],
209
+ 'markerZoomTo' => $this->settings['marker_zoom_to'],
210
  'maxResults' => $dropdown_defaults['max_results'],
211
  'searchRadius' => $dropdown_defaults['search_radius'],
212
  'distanceUnit' => $this->settings['distance_unit'],
213
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
214
  'path' => WPSL_URL,
215
  );
216
+
217
+ /* If the marker clusters are enabled, include the required script and setting values */
218
+ if ( $this->settings['marker_clusters'] ) {
219
+ $settings['clusterZoom'] = $this->settings['cluster_zoom'];
220
+ $settings['clusterSize'] = $this->settings['cluster_size'];
221
+ }
222
+
223
+ /* The __( string, 'wpsl' ) makes the labels accessible in wpml */
224
  $labels = array(
225
+ 'preloader' => stripslashes( __( $this->settings['preloader_label'], 'wpsl' ) ),
226
+ 'noResults' => stripslashes( __( $this->settings['no_results_label'], 'wpsl' ) ),
227
+ 'moreInfo' => stripslashes( __( $this->settings['more_label'], 'wpsl' ) ),
228
+ 'generalError' => stripslashes( __( $this->settings['error_label'], 'wpsl' ) ),
229
+ 'queryLimit' => stripslashes( __( $this->settings['limit_label'], 'wpsl' ) ),
230
+ 'directions' => stripslashes( __( $this->settings['directions_label'], 'wpsl' ) ),
231
+ 'noDirectionsFound' => stripslashes( __( $this->settings['no_directions_label'], 'wpsl' ) ),
232
+ 'phone' => stripslashes( __( $this->settings['phone_label'], 'wpsl' ) ),
233
+ 'fax' => stripslashes( __( $this->settings['fax_label'], 'wpsl' ) ),
234
+ 'hours' => stripslashes( __( $this->settings['hours_label'], 'wpsl' ) ),
235
+ 'startPoint' => stripslashes( __( $this->settings['start_label'], 'wpsl' ) ),
236
+ 'back' => stripslashes( __( $this->settings['back_label'], 'wpsl' ) ),
237
+ 'streetView' => stripslashes( __( $this->settings['street_view_label'], 'wpsl' ) ),
238
+ 'zoomHere' => stripslashes( __( $this->settings['zoom_here_label'], 'wpsl' ) )
239
  );
240
 
241
  wp_localize_script( 'wpsl-js', 'wpslSettings', $settings );
frontend/templates/default.php CHANGED
@@ -8,12 +8,12 @@ $output .= '<div id="wpsl-wrap">' . "\r\n";
8
  $output .= '<div class="wpsl-search clearfix ' . $results_filter_class . '">' . "\r\n";
9
  $output .= '<div id="wpsl-search-wrap">' . "\r\n";
10
  $output .= '<div class="wpsl-input">' . "\r\n";
11
- $output .= '<div><label for="wpsl-search-input">' . esc_html( stripslashes( $this->settings['search_label'] ) ) . '</label></div>' . "\r\n";
12
  $output .= '<input autocomplete="off" id="wpsl-search-input" type="text" value="" name="wpsl-search-input" />' . "\r\n";
13
  $output .= '</div>' . "\r\n";
14
  $output .= '<div class="wpsl-select-wrap">' . "\r\n";
15
  $output .= '<div id="wpsl-radius">' . "\r\n";
16
- $output .= '<label for="wpsl-radius-label">' . esc_html( stripslashes( $this->settings['radius_label'] ) ) . '</label>' . "\r\n";
17
  $output .= '<select autocomplete="off" id="wpsl-radius-label" class="wpsl-dropdown" name="wpsl-radius">' . "\r\n";
18
  $output .= $this->get_dropdown_list( 'search_radius' );
19
  $output .= '</select>' . "\r\n";
@@ -21,14 +21,14 @@ $output .= '</div>' . "\r\n";
21
 
22
  if ( $show_results_filter ) {
23
  $output .= '<div id="wpsl-results">' . "\r\n";
24
- $output .= '<label for="wpsl-results-label">' . esc_html( stripslashes( $this->settings['results_label'] ) ) . '</label>' . "\r\n";
25
  $output .= '<select autocomplete="off" id="wpsl-results-label" class="wpsl-dropdown" name="wpsl-results">' . "\r\n";
26
  $output .= $this->get_dropdown_list( 'max_results' );
27
  $output .= '</select>' . "\r\n";
28
  $output .= '</div>' . "\r\n";
29
  }
30
 
31
- $output .= '<div><input id="wpsl-search-btn" type="submit" value='. esc_attr( stripslashes( $this->settings['search_btn_label'] ) ) . '></div>' . "\r\n";
32
  $output .= '</div>' . "\r\n";
33
  $output .= '</div>' . "\r\n";
34
  $output .= '</div>' . "\r\n";
@@ -52,7 +52,7 @@ if ( $this->settings['reset_map'] ) {
52
  }
53
 
54
  $output .= '<div class="wpsl-gmap-wrap">' . "\r\n";
55
- $output .= '<div id="wpsl-reset-map" ' . $align_class . '>' . stripslashes( $this->settings['reset_label'] ) . '</div>' . "\r\n";
56
  $output .= '<div id="wpsl-gmap"></div>' . "\r\n";
57
  $output .= '</div>' . "\r\n";
58
  } else {
8
  $output .= '<div class="wpsl-search clearfix ' . $results_filter_class . '">' . "\r\n";
9
  $output .= '<div id="wpsl-search-wrap">' . "\r\n";
10
  $output .= '<div class="wpsl-input">' . "\r\n";
11
+ $output .= '<div><label for="wpsl-search-input">' . esc_html_x( stripslashes( $this->settings['search_label'] ), 'wpsl' ) . '</label></div>' . "\r\n";
12
  $output .= '<input autocomplete="off" id="wpsl-search-input" type="text" value="" name="wpsl-search-input" />' . "\r\n";
13
  $output .= '</div>' . "\r\n";
14
  $output .= '<div class="wpsl-select-wrap">' . "\r\n";
15
  $output .= '<div id="wpsl-radius">' . "\r\n";
16
+ $output .= '<label for="wpsl-radius-label">' . esc_html_x( stripslashes( $this->settings['radius_label'] ), 'wpsl' ) . '</label>' . "\r\n";
17
  $output .= '<select autocomplete="off" id="wpsl-radius-label" class="wpsl-dropdown" name="wpsl-radius">' . "\r\n";
18
  $output .= $this->get_dropdown_list( 'search_radius' );
19
  $output .= '</select>' . "\r\n";
21
 
22
  if ( $show_results_filter ) {
23
  $output .= '<div id="wpsl-results">' . "\r\n";
24
+ $output .= '<label for="wpsl-results-label">' . esc_html_x( stripslashes( $this->settings['results_label'] ), 'wpsl' ) . '</label>' . "\r\n";
25
  $output .= '<select autocomplete="off" id="wpsl-results-label" class="wpsl-dropdown" name="wpsl-results">' . "\r\n";
26
  $output .= $this->get_dropdown_list( 'max_results' );
27
  $output .= '</select>' . "\r\n";
28
  $output .= '</div>' . "\r\n";
29
  }
30
 
31
+ $output .= '<div><input id="wpsl-search-btn" type="submit" value='. esc_attr_x( stripslashes( $this->settings['search_btn_label'] ), 'wpsl' ) . '></div>' . "\r\n";
32
  $output .= '</div>' . "\r\n";
33
  $output .= '</div>' . "\r\n";
34
  $output .= '</div>' . "\r\n";
52
  }
53
 
54
  $output .= '<div class="wpsl-gmap-wrap">' . "\r\n";
55
+ $output .= '<div id="wpsl-reset-map" ' . $align_class . '>' . esc_html_x( stripslashes( $this->settings['reset_label'] ), 'wpsl' ) . '</div>' . "\r\n";
56
  $output .= '<div id="wpsl-gmap"></div>' . "\r\n";
57
  $output .= '</div>' . "\r\n";
58
  } else {
frontend/templates/store-listings-below.php CHANGED
@@ -8,12 +8,12 @@ $output .= '<div id="wpsl-wrap" class="wpsl-store-below">' . "\r\n";
8
  $output .= '<div class="wpsl-search clearfix ' . $results_filter_class . '">' . "\r\n";
9
  $output .= '<div id="wpsl-search-wrap">' . "\r\n";
10
  $output .= '<div class="wpsl-input">' . "\r\n";
11
- $output .= '<div><label for="wpsl-search-input">' . esc_html( stripslashes( $this->settings['search_label'] ) ) . '</label></div>' . "\r\n";
12
  $output .= '<input autocomplete="off" id="wpsl-search-input" type="text" value="" name="wpsl-search-input" />' . "\r\n";
13
  $output .= '</div>' . "\r\n";
14
  $output .= '<div class="wpsl-select-wrap">' . "\r\n";
15
  $output .= '<div id="wpsl-radius">' . "\r\n";
16
- $output .= '<label for="wpsl-radius-label">' . esc_html( stripslashes( $this->settings['radius_label'] ) ).'</label>' . "\r\n";
17
  $output .= '<select autocomplete="off" id="wpsl-radius-label" class="wpsl-dropdown" name="wpsl-radius">' . "\r\n";
18
  $output .= $this->get_dropdown_list( 'search_radius' );
19
  $output .= '</select>' . "\r\n";
@@ -21,14 +21,14 @@ $output .= '</div>' . "\r\n";
21
 
22
  if ( $show_results_filter ) {
23
  $output .= '<div id="wpsl-results">' . "\r\n";
24
- $output .= '<label for="wpsl-results-label">' . esc_html( stripslashes( $this->settings['results_label'] ) ) . '</label>' . "\r\n";
25
  $output .= '<select autocomplete="off" id="wpsl-results-label" class="wpsl-dropdown" name="wpsl-results">' . "\r\n";
26
  $output .= $this->get_dropdown_list( 'max_results' );
27
  $output .= '</select>' . "\r\n";
28
  $output .= '</div>' . "\r\n";
29
  }
30
 
31
- $output .= '<div><input id="wpsl-search-btn" type="submit" value='. esc_attr( stripslashes( $this->settings['search_btn_label'] ) ) . '></div>' . "\r\n";
32
  $output .= '</div>' . "\r\n";
33
  $output .= '</div>' . "\r\n";
34
  $output .= '</div>' . "\r\n";
@@ -43,7 +43,7 @@ if ( $this->settings['reset_map'] ) {
43
  }
44
 
45
  $output .= '<div class="wpsl-gmap-wrap">' . "\r\n";
46
- $output .= '<div id="wpsl-reset-map" ' . $align_class . '>' . stripslashes( $this->settings['reset_label'] ) . '</div>' . "\r\n";
47
  $output .= '<div id="wpsl-gmap"></div>' . "\r\n";
48
  $output .= '</div>' . "\r\n";
49
  } else {
8
  $output .= '<div class="wpsl-search clearfix ' . $results_filter_class . '">' . "\r\n";
9
  $output .= '<div id="wpsl-search-wrap">' . "\r\n";
10
  $output .= '<div class="wpsl-input">' . "\r\n";
11
+ $output .= '<div><label for="wpsl-search-input">' . esc_html_x( stripslashes( $this->settings['search_label'] ), 'wpsl' ) . '</label></div>' . "\r\n";
12
  $output .= '<input autocomplete="off" id="wpsl-search-input" type="text" value="" name="wpsl-search-input" />' . "\r\n";
13
  $output .= '</div>' . "\r\n";
14
  $output .= '<div class="wpsl-select-wrap">' . "\r\n";
15
  $output .= '<div id="wpsl-radius">' . "\r\n";
16
+ $output .= '<label for="wpsl-radius-label">' . esc_html_x( stripslashes( $this->settings['radius_label'] ), 'wpsl' ).'</label>' . "\r\n";
17
  $output .= '<select autocomplete="off" id="wpsl-radius-label" class="wpsl-dropdown" name="wpsl-radius">' . "\r\n";
18
  $output .= $this->get_dropdown_list( 'search_radius' );
19
  $output .= '</select>' . "\r\n";
21
 
22
  if ( $show_results_filter ) {
23
  $output .= '<div id="wpsl-results">' . "\r\n";
24
+ $output .= '<label for="wpsl-results-label">' . esc_html_x( stripslashes( $this->settings['results_label'] ), 'wpsl' ) . '</label>' . "\r\n";
25
  $output .= '<select autocomplete="off" id="wpsl-results-label" class="wpsl-dropdown" name="wpsl-results">' . "\r\n";
26
  $output .= $this->get_dropdown_list( 'max_results' );
27
  $output .= '</select>' . "\r\n";
28
  $output .= '</div>' . "\r\n";
29
  }
30
 
31
+ $output .= '<div><input id="wpsl-search-btn" type="submit" value='. esc_attr_x( stripslashes( $this->settings['search_btn_label'] ), 'wpsl' ) . '></div>' . "\r\n";
32
  $output .= '</div>' . "\r\n";
33
  $output .= '</div>' . "\r\n";
34
  $output .= '</div>' . "\r\n";
43
  }
44
 
45
  $output .= '<div class="wpsl-gmap-wrap">' . "\r\n";
46
+ $output .= '<div id="wpsl-reset-map" ' . $align_class . '>' . esc_html_x( stripslashes( $this->settings['reset_label'] ), 'wpsl' ) . '</div>' . "\r\n";
47
  $output .= '<div id="wpsl-gmap"></div>' . "\r\n";
48
  $output .= '</div>' . "\r\n";
49
  } else {
frontend/wpsl-ajax-functions.php CHANGED
@@ -18,21 +18,24 @@ function wpsl_store_search() {
18
 
19
  $options = get_option( 'wpsl_settings' );
20
  $distance_unit = ( $options['distance_unit'] == 'km' ) ? '6371' : '3959';
21
-
22
- /* If no max results is set, we get the default value from the settings.
23
- * The only situation when it can be empty, is when the "Show the limit results dropdown"
24
- * checkbox is unchecked on the settings page.
25
- */
26
- if ( ( $_GET['max_results'] == 'NaN' ) || ( !$_GET['max_results'] ) ) {
27
- $max_results = get_default_list_value( $type = 'max_results' );
28
- } else {
29
- $max_results = $_GET['max_results'];
30
- }
31
 
32
  /* Check if we need to include the distance and radius limit in the sql query.
33
  * If autoload is enabled we load all stores, so no limits required.
34
  */
35
- if ( !$_GET['autoload'] ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  $sql_part = ' HAVING distance < %d ORDER BY distance LIMIT 0, %d';
37
  $placeholders = array(
38
  $_GET["lat"],
@@ -40,14 +43,7 @@ function wpsl_store_search() {
40
  $_GET["lat"],
41
  $_GET["radius"],
42
  $max_results
43
- );
44
- } else {
45
- $sql_part = ' ORDER BY distance';
46
- $placeholders = array(
47
- $_GET["lat"],
48
- $_GET["lng"],
49
- $_GET["lat"]
50
- );
51
  }
52
 
53
  $result = $wpdb->get_results(
@@ -78,7 +74,8 @@ function wpsl_store_search() {
78
  $store_results[] = array (
79
  'id' => absint( $result[$k]->wpsl_id ),
80
  'store' => sanitize_text_field( stripslashes( $result[$k]->store ) ),
81
- 'street' => sanitize_text_field( stripslashes( $result[$k]->street ) ),
 
82
  'city' => sanitize_text_field( stripslashes( $result[$k]->city ) ),
83
  'state' => sanitize_text_field( stripslashes( $result[$k]->state ) ),
84
  'zip' => sanitize_text_field( stripslashes( $result[$k]->zip ) ),
@@ -111,7 +108,7 @@ function wpsl_store_search() {
111
  */
112
  function get_default_list_value( $type ) {
113
 
114
- $settings = get_option( 'wpsl_settings' );
115
  $list_values = explode( ',', $settings[$type] );
116
 
117
  foreach ( $list_values as $k => $list_value ) {
18
 
19
  $options = get_option( 'wpsl_settings' );
20
  $distance_unit = ( $options['distance_unit'] == 'km' ) ? '6371' : '3959';
 
 
 
 
 
 
 
 
 
 
21
 
22
  /* Check if we need to include the distance and radius limit in the sql query.
23
  * If autoload is enabled we load all stores, so no limits required.
24
  */
25
+ if ( isset( $_GET['autoload'] ) && ( $_GET['autoload'] == 1 ) ) {
26
+ $sql_part = ' ORDER BY distance';
27
+ $placeholders = array(
28
+ $_GET["lat"],
29
+ $_GET["lng"],
30
+ $_GET["lat"]
31
+ );
32
+ } else {
33
+ $max_results = ( isset( $_GET['max_results'] ) ) ? $_GET['max_results'] : '';
34
+
35
+ if ( ( $max_results == 'NaN' ) || ( !$max_results ) ) {
36
+ $max_results = get_default_list_value( $type = 'max_results' );
37
+ }
38
+
39
  $sql_part = ' HAVING distance < %d ORDER BY distance LIMIT 0, %d';
40
  $placeholders = array(
41
  $_GET["lat"],
43
  $_GET["lat"],
44
  $_GET["radius"],
45
  $max_results
46
+ );
 
 
 
 
 
 
 
47
  }
48
 
49
  $result = $wpdb->get_results(
74
  $store_results[] = array (
75
  'id' => absint( $result[$k]->wpsl_id ),
76
  'store' => sanitize_text_field( stripslashes( $result[$k]->store ) ),
77
+ 'address' => sanitize_text_field( stripslashes( $result[$k]->address ) ),
78
+ 'address2' => sanitize_text_field( stripslashes( $result[$k]->address2 ) ),
79
  'city' => sanitize_text_field( stripslashes( $result[$k]->city ) ),
80
  'state' => sanitize_text_field( stripslashes( $result[$k]->state ) ),
81
  'zip' => sanitize_text_field( stripslashes( $result[$k]->zip ) ),
108
  */
109
  function get_default_list_value( $type ) {
110
 
111
+ $settings = get_option( 'wpsl_settings' );
112
  $list_values = explode( ',', $settings[$type] );
113
 
114
  foreach ( $list_values as $k => $list_value ) {
js/jquery.easydropdown.js CHANGED
@@ -1,6 +1,6 @@
1
  /*
2
  * EASYDROPDOWN - A Drop-down Builder for Styleable Inputs and Menus
3
- * Version: 2.1.3
4
  * License: Creative Commons Attribution 3.0 Unported - CC BY 3.0
5
  * http://creativecommons.org/licenses/by/3.0/
6
  * This software may be used freely on commercial and non-commercial projects with attribution to the author/copyright holder.
@@ -26,7 +26,7 @@
26
 
27
  EasyDropDown.prototype = {
28
  constructor: EasyDropDown,
29
- instances: [],
30
  init: function(domNode, settings){
31
  var self = this;
32
 
@@ -91,8 +91,23 @@
91
  self.$dropDown.append('<li'+active+'>'+option.title+'</li>');
92
  });
93
  self.$items = self.$dropDown.find('li');
94
- self.maxHeight = 0;
95
  if(self.cutOff && self.$items.length > self.cutOff)self.$container.addClass('scrollable');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  for(i = 0; i < self.$items.length; i++){
97
  var $item = self.$items.eq(i);
98
  self.maxHeight += $item.outerHeight();
@@ -100,12 +115,6 @@
100
  break;
101
  };
102
  };
103
-
104
- if(self.isTouch && self.nativeTouch){
105
- self.bindTouchHandlers();
106
- } else {
107
- self.bindHandlers();
108
- };
109
  },
110
 
111
  bindTouchHandlers: function(){
@@ -280,6 +289,7 @@
280
  scrollOffset = self.notInViewport(scrollTop);
281
 
282
  self.closeAll();
 
283
  self.$select.focus();
284
  window.scrollTo(scrollLeft, scrollTop+scrollOffset);
285
  self.$container.addClass('open');
1
  /*
2
  * EASYDROPDOWN - A Drop-down Builder for Styleable Inputs and Menus
3
+ * Version: 2.1.4
4
  * License: Creative Commons Attribution 3.0 Unported - CC BY 3.0
5
  * http://creativecommons.org/licenses/by/3.0/
6
  * This software may be used freely on commercial and non-commercial projects with attribution to the author/copyright holder.
26
 
27
  EasyDropDown.prototype = {
28
  constructor: EasyDropDown,
29
+ instances: {},
30
  init: function(domNode, settings){
31
  var self = this;
32
 
91
  self.$dropDown.append('<li'+active+'>'+option.title+'</li>');
92
  });
93
  self.$items = self.$dropDown.find('li');
94
+
95
  if(self.cutOff && self.$items.length > self.cutOff)self.$container.addClass('scrollable');
96
+
97
+ self.getMaxHeight();
98
+
99
+ if(self.isTouch && self.nativeTouch){
100
+ self.bindTouchHandlers();
101
+ } else {
102
+ self.bindHandlers();
103
+ };
104
+ },
105
+
106
+ getMaxHeight: function(){
107
+ var self = this;
108
+
109
+ self.maxHeight = 0;
110
+
111
  for(i = 0; i < self.$items.length; i++){
112
  var $item = self.$items.eq(i);
113
  self.maxHeight += $item.outerHeight();
115
  break;
116
  };
117
  };
 
 
 
 
 
 
118
  },
119
 
120
  bindTouchHandlers: function(){
289
  scrollOffset = self.notInViewport(scrollTop);
290
 
291
  self.closeAll();
292
+ self.getMaxHeight();
293
  self.$select.focus();
294
  window.scrollTo(scrollLeft, scrollTop+scrollOffset);
295
  self.$container.addClass('open');
js/jquery.easydropdown.min.js CHANGED
@@ -1,6 +1,6 @@
1
  /*
2
  * EASYDROPDOWN - A Drop-down Builder for Styleable Inputs and Menus
3
- * Version: 2.1.3
4
  * License: Creative Commons Attribution 3.0 Unported - CC BY 3.0
5
  * http://creativecommons.org/licenses/by/3.0/
6
  * This software may be used freely on commercial and non-commercial projects with attribution to the author/copyright holder.
@@ -8,17 +8,17 @@
8
  * Copyright 2013 Patrick Kunka, All Rights Reserved
9
  */
10
 
11
- (function(d){function e(){this.isField=!0;this.keyboardMode=this.hasLabel=this.cutOff=this.disabled=this.inFocus=this.down=!1;this.nativeTouch=!0;this.wrapperClass="dropdown";this.onChange=null}e.prototype={constructor:e,instances:[],init:function(a,c){var b=this;d.extend(b,c);b.$select=d(a);b.id=a.id;b.options=[];b.$options=b.$select.find("option");b.isTouch="ontouchend"in document;b.$select.removeClass(b.wrapperClass+" dropdown");b.$select.is(":disabled")&&(b.disabled=!0);b.$options.length&&(b.$options.each(function(a){var c=
12
  d(this);c.is(":selected")&&(b.selected={index:a,title:c.text()},b.focusIndex=a);c.hasClass("label")&&0==a?(b.hasLabel=!0,b.label=c.text(),c.attr("value","")):b.options.push({domNode:c[0],title:c.text(),value:c.val(),selected:c.is(":selected")})}),b.selected||(b.selected={index:0,title:b.$options.eq(0).text()},b.focusIndex=0),b.render())},render:function(){var a=this;a.$container=a.$select.wrap('<div class="'+a.wrapperClass+(a.isTouch&&a.nativeTouch?" touch":"")+(a.disabled?" disabled":"")+'"><span class="old"/></div>').parent().parent();
13
- a.$active=d('<span class="selected">'+a.selected.title+"</span>").appendTo(a.$container);a.$carat=d('<span class="carat"/>').appendTo(a.$container);a.$scrollWrapper=d("<div><ul/></div>").appendTo(a.$container);a.$dropDown=a.$scrollWrapper.find("ul");a.$form=a.$container.closest("form");d.each(a.options,function(){a.$dropDown.append("<li"+(this.selected?' class="active"':"")+">"+this.title+"</li>")});a.$items=a.$dropDown.find("li");a.maxHeight=0;a.cutOff&&a.$items.length>a.cutOff&&a.$container.addClass("scrollable");
14
- for(i=0;i<a.$items.length;i++){var c=a.$items.eq(i);a.maxHeight+=c.outerHeight();if(a.cutOff==i+1)break}a.isTouch&&a.nativeTouch?a.bindTouchHandlers():a.bindHandlers()},bindTouchHandlers:function(){var a=this;a.$container.on("click.easyDropDown",function(){a.$select.focus()});a.$select.on({change:function(){var c=d(this).find("option:selected"),b=c.text(),c=c.val();a.$active.text(b);"function"===typeof a.onChange&&a.onChange.call(a.$select[0],{title:b,value:c})},focus:function(){a.$container.addClass("focus")},
15
- blur:function(){a.$container.removeClass("focus")}})},bindHandlers:function(){var a=this;a.query="";a.$container.on({"click.easyDropDown":function(){a.down||a.disabled?a.close():a.open()},"mousemove.easyDropDown":function(){a.keyboardMode&&(a.keyboardMode=!1)}});d("body").on("click.easyDropDown."+a.id,function(c){c=d(c.target);var b=a.wrapperClass.split(" ").join(".");!c.closest("."+b).length&&a.down&&a.close()});a.$items.on({"click.easyDropDown":function(){var c=d(this).index();a.select(c);a.$select.focus()},
16
- "mouseover.easyDropDown":function(){if(!a.keyboardMode){var c=d(this);c.addClass("focus").siblings().removeClass("focus");a.focusIndex=c.index()}},"mouseout.easyDropDown":function(){a.keyboardMode||d(this).removeClass("focus")}});a.$select.on({"focus.easyDropDown":function(){a.$container.addClass("focus");a.inFocus=!0},"blur.easyDropDown":function(){a.$container.removeClass("focus");a.inFocus=!1},"keydown.easyDropDown":function(c){if(a.inFocus){a.keyboardMode=!0;var b=c.keyCode;if(38==b||40==b||32==
17
- b)c.preventDefault(),38==b?(a.focusIndex--,a.focusIndex=0>a.focusIndex?a.$items.length-1:a.focusIndex):40==b&&(a.focusIndex++,a.focusIndex=a.focusIndex>a.$items.length-1?0:a.focusIndex),a.down||a.open(),a.$items.removeClass("focus").eq(a.focusIndex).addClass("focus"),a.cutOff&&a.scrollToView(),a.query="";if(a.down)if(9==b||27==b)a.close();else{if(13==b)return c.preventDefault(),a.select(a.focusIndex),a.close(),!1;if(8==b)return c.preventDefault(),a.query=a.query.slice(0,-1),a.search(),clearTimeout(a.resetQuery),
18
- !1;38!=b&&40!=b&&(c=String.fromCharCode(b),a.query+=c,a.search(),clearTimeout(a.resetQuery))}}},"keyup.easyDropDown":function(){a.resetQuery=setTimeout(function(){a.query=""},1200)}});a.$dropDown.on("scroll.easyDropDown",function(c){a.$dropDown[0].scrollTop>=a.$dropDown[0].scrollHeight-a.maxHeight?a.$container.addClass("bottom"):a.$container.removeClass("bottom")});if(a.$form.length)a.$form.on("reset.easyDropDown",function(){a.$active.text(a.hasLabel?a.label:a.options[0].title)})},unbindHandlers:function(){this.$container.add(this.$select).add(this.$items).add(this.$form).add(this.$dropDown).off(".easyDropDown");
19
- d("body").off("."+this.id)},open:function(){var a=window.scrollY||document.documentElement.scrollTop,c=window.scrollX||document.documentElement.scrollLeft,b=this.notInViewport(a);this.closeAll();this.$select.focus();window.scrollTo(c,a+b);this.$container.addClass("open");this.$scrollWrapper.css("height",this.maxHeight+"px");this.down=!0},close:function(){this.$container.removeClass("open");this.$scrollWrapper.css("height","0px");this.focusIndex=this.selected.index;this.query="";this.down=!1},closeAll:function(){var a=
20
- Object.getPrototypeOf(this).instances,c;for(c in a)a[c].close()},select:function(a){"string"===typeof a&&(a=this.$select.find("option[value="+a+"]").index()-1);var c=this.options[a],b=this.hasLabel?a+1:a;this.$items.removeClass("active").eq(a).addClass("active");this.$active.text(c.title);this.$select.find("option").removeAttr("selected").eq(b).prop("selected",!0).parent().trigger("change");this.selected={index:a,title:c.title};this.focusIndex=i;"function"===typeof this.onChange&&this.onChange.call(this.$select[0],
21
- {title:c.title,value:c.value})},search:function(){var a=this,c=function(b){a.focusIndex=b;a.$items.removeClass("focus").eq(a.focusIndex).addClass("focus");a.scrollToView()};for(i=0;i<a.options.length;i++){var b=a.options[i].title.toUpperCase();if(0==b.indexOf(a.query)){c(i);return}}for(i=0;i<a.options.length;i++)if(b=a.options[i].title.toUpperCase(),-1<b.indexOf(a.query)){c(i);break}},scrollToView:function(){if(this.focusIndex>=this.cutOff){var a=this.$items.eq(this.focusIndex).outerHeight()*(this.focusIndex+
22
- 1)-this.maxHeight;this.$dropDown.scrollTop(a)}},notInViewport:function(a){var c=a+(window.innerHeight||document.documentElement.clientHeight),b=this.$dropDown.offset().top+this.maxHeight;return b>=a&&b<=c?0:b-c+5},destroy:function(){this.unbindHandlers();this.$select.unwrap().siblings().remove();this.$select.unwrap();delete Object.getPrototypeOf(this).instances[this.$select[0].id]},disable:function(){this.disabled=!0;this.$container.addClass("disabled");this.$select.attr("disabled",!0);this.down||
23
- this.close()},enable:function(){this.disabled=!1;this.$container.removeClass("disabled");this.$select.attr("disabled",!1)}};var f=function(a,c){a.id=a.id?a.id:"EasyDropDown"+("00000"+(16777216*Math.random()<<0).toString(16)).substr(-6).toUpperCase();var b=new e;b.instances[a.id]||(b.instances[a.id]=b,b.init(a,c))};d.fn.easyDropDown=function(){var a=arguments,c=[],b;b=this.each(function(){if(a&&"string"===typeof a[0]){var b=e.prototype.instances[this.id][a[0]](a[1],a[2]);b&&c.push(b)}else f(this,a[0])});
24
- return c.length?1<c.length?c:c[0]:b};d(function(){"function"!==typeof Object.getPrototypeOf&&(Object.getPrototypeOf="object"===typeof"test".__proto__?function(a){return a.__proto__}:function(a){return a.constructor.prototype});d("select.dropdown").each(function(){var a=d(this).attr("data-settings");settings=a?d.parseJSON(a):{};f(this,settings)})})})(jQuery);
1
  /*
2
  * EASYDROPDOWN - A Drop-down Builder for Styleable Inputs and Menus
3
+ * Version: 2.1.4
4
  * License: Creative Commons Attribution 3.0 Unported - CC BY 3.0
5
  * http://creativecommons.org/licenses/by/3.0/
6
  * This software may be used freely on commercial and non-commercial projects with attribution to the author/copyright holder.
8
  * Copyright 2013 Patrick Kunka, All Rights Reserved
9
  */
10
 
11
+ (function(d){function e(){this.isField=!0;this.keyboardMode=this.hasLabel=this.cutOff=this.disabled=this.inFocus=this.down=!1;this.nativeTouch=!0;this.wrapperClass="dropdown";this.onChange=null}e.prototype={constructor:e,instances:{},init:function(a,c){var b=this;d.extend(b,c);b.$select=d(a);b.id=a.id;b.options=[];b.$options=b.$select.find("option");b.isTouch="ontouchend"in document;b.$select.removeClass(b.wrapperClass+" dropdown");b.$select.is(":disabled")&&(b.disabled=!0);b.$options.length&&(b.$options.each(function(a){var c=
12
  d(this);c.is(":selected")&&(b.selected={index:a,title:c.text()},b.focusIndex=a);c.hasClass("label")&&0==a?(b.hasLabel=!0,b.label=c.text(),c.attr("value","")):b.options.push({domNode:c[0],title:c.text(),value:c.val(),selected:c.is(":selected")})}),b.selected||(b.selected={index:0,title:b.$options.eq(0).text()},b.focusIndex=0),b.render())},render:function(){var a=this;a.$container=a.$select.wrap('<div class="'+a.wrapperClass+(a.isTouch&&a.nativeTouch?" touch":"")+(a.disabled?" disabled":"")+'"><span class="old"/></div>').parent().parent();
13
+ a.$active=d('<span class="selected">'+a.selected.title+"</span>").appendTo(a.$container);a.$carat=d('<span class="carat"/>').appendTo(a.$container);a.$scrollWrapper=d("<div><ul/></div>").appendTo(a.$container);a.$dropDown=a.$scrollWrapper.find("ul");a.$form=a.$container.closest("form");d.each(a.options,function(){a.$dropDown.append("<li"+(this.selected?' class="active"':"")+">"+this.title+"</li>")});a.$items=a.$dropDown.find("li");a.cutOff&&a.$items.length>a.cutOff&&a.$container.addClass("scrollable");
14
+ a.getMaxHeight();a.isTouch&&a.nativeTouch?a.bindTouchHandlers():a.bindHandlers()},getMaxHeight:function(){for(i=this.maxHeight=0;i<this.$items.length;i++){var a=this.$items.eq(i);this.maxHeight+=a.outerHeight();if(this.cutOff==i+1)break}},bindTouchHandlers:function(){var a=this;a.$container.on("click.easyDropDown",function(){a.$select.focus()});a.$select.on({change:function(){var c=d(this).find("option:selected"),b=c.text(),c=c.val();a.$active.text(b);"function"===typeof a.onChange&&a.onChange.call(a.$select[0],
15
+ {title:b,value:c})},focus:function(){a.$container.addClass("focus")},blur:function(){a.$container.removeClass("focus")}})},bindHandlers:function(){var a=this;a.query="";a.$container.on({"click.easyDropDown":function(){a.down||a.disabled?a.close():a.open()},"mousemove.easyDropDown":function(){a.keyboardMode&&(a.keyboardMode=!1)}});d("body").on("click.easyDropDown."+a.id,function(c){c=d(c.target);var b=a.wrapperClass.split(" ").join(".");!c.closest("."+b).length&&a.down&&a.close()});a.$items.on({"click.easyDropDown":function(){var c=
16
+ d(this).index();a.select(c);a.$select.focus()},"mouseover.easyDropDown":function(){if(!a.keyboardMode){var c=d(this);c.addClass("focus").siblings().removeClass("focus");a.focusIndex=c.index()}},"mouseout.easyDropDown":function(){a.keyboardMode||d(this).removeClass("focus")}});a.$select.on({"focus.easyDropDown":function(){a.$container.addClass("focus");a.inFocus=!0},"blur.easyDropDown":function(){a.$container.removeClass("focus");a.inFocus=!1},"keydown.easyDropDown":function(c){if(a.inFocus){a.keyboardMode=
17
+ !0;var b=c.keyCode;if(38==b||40==b||32==b)c.preventDefault(),38==b?(a.focusIndex--,a.focusIndex=0>a.focusIndex?a.$items.length-1:a.focusIndex):40==b&&(a.focusIndex++,a.focusIndex=a.focusIndex>a.$items.length-1?0:a.focusIndex),a.down||a.open(),a.$items.removeClass("focus").eq(a.focusIndex).addClass("focus"),a.cutOff&&a.scrollToView(),a.query="";if(a.down)if(9==b||27==b)a.close();else{if(13==b)return c.preventDefault(),a.select(a.focusIndex),a.close(),!1;if(8==b)return c.preventDefault(),a.query=a.query.slice(0,
18
+ -1),a.search(),clearTimeout(a.resetQuery),!1;38!=b&&40!=b&&(c=String.fromCharCode(b),a.query+=c,a.search(),clearTimeout(a.resetQuery))}}},"keyup.easyDropDown":function(){a.resetQuery=setTimeout(function(){a.query=""},1200)}});a.$dropDown.on("scroll.easyDropDown",function(c){a.$dropDown[0].scrollTop>=a.$dropDown[0].scrollHeight-a.maxHeight?a.$container.addClass("bottom"):a.$container.removeClass("bottom")});if(a.$form.length)a.$form.on("reset.easyDropDown",function(){a.$active.text(a.hasLabel?a.label:
19
+ a.options[0].title)})},unbindHandlers:function(){this.$container.add(this.$select).add(this.$items).add(this.$form).add(this.$dropDown).off(".easyDropDown");d("body").off("."+this.id)},open:function(){var a=window.scrollY||document.documentElement.scrollTop,c=window.scrollX||document.documentElement.scrollLeft,b=this.notInViewport(a);this.closeAll();this.getMaxHeight();this.$select.focus();window.scrollTo(c,a+b);this.$container.addClass("open");this.$scrollWrapper.css("height",this.maxHeight+"px");
20
+ this.down=!0},close:function(){this.$container.removeClass("open");this.$scrollWrapper.css("height","0px");this.focusIndex=this.selected.index;this.query="";this.down=!1},closeAll:function(){var a=Object.getPrototypeOf(this).instances,c;for(c in a)a[c].close()},select:function(a){"string"===typeof a&&(a=this.$select.find("option[value="+a+"]").index()-1);var c=this.options[a],b=this.hasLabel?a+1:a;this.$items.removeClass("active").eq(a).addClass("active");this.$active.text(c.title);this.$select.find("option").removeAttr("selected").eq(b).prop("selected",
21
+ !0).parent().trigger("change");this.selected={index:a,title:c.title};this.focusIndex=i;"function"===typeof this.onChange&&this.onChange.call(this.$select[0],{title:c.title,value:c.value})},search:function(){var a=this,c=function(b){a.focusIndex=b;a.$items.removeClass("focus").eq(a.focusIndex).addClass("focus");a.scrollToView()};for(i=0;i<a.options.length;i++){var b=a.options[i].title.toUpperCase();if(0==b.indexOf(a.query)){c(i);return}}for(i=0;i<a.options.length;i++)if(b=a.options[i].title.toUpperCase(),
22
+ -1<b.indexOf(a.query)){c(i);break}},scrollToView:function(){if(this.focusIndex>=this.cutOff){var a=this.$items.eq(this.focusIndex).outerHeight()*(this.focusIndex+1)-this.maxHeight;this.$dropDown.scrollTop(a)}},notInViewport:function(a){var c=a+(window.innerHeight||document.documentElement.clientHeight),b=this.$dropDown.offset().top+this.maxHeight;return b>=a&&b<=c?0:b-c+5},destroy:function(){this.unbindHandlers();this.$select.unwrap().siblings().remove();this.$select.unwrap();delete Object.getPrototypeOf(this).instances[this.$select[0].id]},
23
+ disable:function(){this.disabled=!0;this.$container.addClass("disabled");this.$select.attr("disabled",!0);this.down||this.close()},enable:function(){this.disabled=!1;this.$container.removeClass("disabled");this.$select.attr("disabled",!1)}};var f=function(a,c){a.id=a.id?a.id:"EasyDropDown"+("00000"+(16777216*Math.random()<<0).toString(16)).substr(-6).toUpperCase();var b=new e;b.instances[a.id]||(b.instances[a.id]=b,b.init(a,c))};d.fn.easyDropDown=function(){var a=arguments,c=[],b;b=this.each(function(){if(a&&
24
+ "string"===typeof a[0]){var b=e.prototype.instances[this.id][a[0]](a[1],a[2]);b&&c.push(b)}else f(this,a[0])});return c.length?1<c.length?c:c[0]:b};d(function(){"function"!==typeof Object.getPrototypeOf&&(Object.getPrototypeOf="object"===typeof"test".__proto__?function(a){return a.__proto__}:function(a){return a.constructor.prototype});d("select.dropdown").each(function(){var a=d(this).attr("data-settings");settings=a?d.parseJSON(a):{};f(this,settings)})})})(jQuery);
js/markerclusterer.js ADDED
@@ -0,0 +1,1310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ==ClosureCompiler==
2
+ // @compilation_level ADVANCED_OPTIMIZATIONS
3
+ // @externs_url http://closure-compiler.googlecode.com/svn/trunk/contrib/externs/maps/google_maps_api_v3_3.js
4
+ // ==/ClosureCompiler==
5
+
6
+ /**
7
+ * @name MarkerClusterer for Google Maps v3
8
+ * @version version 1.0.1
9
+ * @author Luke Mahe
10
+ * @fileoverview
11
+ * The library creates and manages per-zoom-level clusters for large amounts of
12
+ * markers.
13
+ * <br/>
14
+ * This is a v3 implementation of the
15
+ * <a href="http://gmaps-utility-library-dev.googlecode.com/svn/tags/markerclusterer/"
16
+ * >v2 MarkerClusterer</a>.
17
+ */
18
+
19
+ /**
20
+ * Licensed under the Apache License, Version 2.0 (the "License");
21
+ * you may not use this file except in compliance with the License.
22
+ * You may obtain a copy of the License at
23
+ *
24
+ * http://www.apache.org/licenses/LICENSE-2.0
25
+ *
26
+ * Unless required by applicable law or agreed to in writing, software
27
+ * distributed under the License is distributed on an "AS IS" BASIS,
28
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29
+ * See the License for the specific language governing permissions and
30
+ * limitations under the License.
31
+ */
32
+
33
+
34
+ /**
35
+ * A Marker Clusterer that clusters markers.
36
+ *
37
+ * @param {google.maps.Map} map The Google map to attach to.
38
+ * @param {Array.<google.maps.Marker>=} opt_markers Optional markers to add to
39
+ * the cluster.
40
+ * @param {Object=} opt_options support the following options:
41
+ * 'gridSize': (number) The grid size of a cluster in pixels.
42
+ * 'maxZoom': (number) The maximum zoom level that a marker can be part of a
43
+ * cluster.
44
+ * 'zoomOnClick': (boolean) Whether the default behaviour of clicking on a
45
+ * cluster is to zoom into it.
46
+ * 'averageCenter': (boolean) Wether the center of each cluster should be
47
+ * the average of all markers in the cluster.
48
+ * 'minimumClusterSize': (number) The minimum number of markers to be in a
49
+ * cluster before the markers are hidden and a count
50
+ * is shown.
51
+ * 'styles': (object) An object that has style properties:
52
+ * 'url': (string) The image url.
53
+ * 'height': (number) The image height.
54
+ * 'width': (number) The image width.
55
+ * 'anchor': (Array) The anchor position of the label text.
56
+ * 'textColor': (string) The text color.
57
+ * 'textSize': (number) The text size.
58
+ * 'backgroundPosition': (string) The position of the backgound x, y.
59
+ * @constructor
60
+ * @extends google.maps.OverlayView
61
+ */
62
+ function MarkerClusterer(map, opt_markers, opt_options) {
63
+ // MarkerClusterer implements google.maps.OverlayView interface. We use the
64
+ // extend function to extend MarkerClusterer with google.maps.OverlayView
65
+ // because it might not always be available when the code is defined so we
66
+ // look for it at the last possible moment. If it doesn't exist now then
67
+ // there is no point going ahead :)
68
+ this.extend(MarkerClusterer, google.maps.OverlayView);
69
+ this.map_ = map;
70
+
71
+ /**
72
+ * @type {Array.<google.maps.Marker>}
73
+ * @private
74
+ */
75
+ this.markers_ = [];
76
+
77
+ /**
78
+ * @type {Array.<Cluster>}
79
+ */
80
+ this.clusters_ = [];
81
+
82
+ this.sizes = [53, 56, 66, 78, 90];
83
+
84
+ /**
85
+ * @private
86
+ */
87
+ this.styles_ = [];
88
+
89
+ /**
90
+ * @type {boolean}
91
+ * @private
92
+ */
93
+ this.ready_ = false;
94
+
95
+ var options = opt_options || {};
96
+
97
+ /**
98
+ * @type {number}
99
+ * @private
100
+ */
101
+ this.gridSize_ = options['gridSize'] || 60;
102
+
103
+ /**
104
+ * @private
105
+ */
106
+ this.minClusterSize_ = options['minimumClusterSize'] || 2;
107
+
108
+
109
+ /**
110
+ * @type {?number}
111
+ * @private
112
+ */
113
+ this.maxZoom_ = options['maxZoom'] || null;
114
+
115
+ this.styles_ = options['styles'] || [];
116
+
117
+ /**
118
+ * @type {string}
119
+ * @private
120
+ */
121
+ this.imagePath_ = options['imagePath'] ||
122
+ this.MARKER_CLUSTER_IMAGE_PATH_;
123
+
124
+ /**
125
+ * @type {string}
126
+ * @private
127
+ */
128
+ this.imageExtension_ = options['imageExtension'] ||
129
+ this.MARKER_CLUSTER_IMAGE_EXTENSION_;
130
+
131
+ /**
132
+ * @type {boolean}
133
+ * @private
134
+ */
135
+ this.zoomOnClick_ = true;
136
+
137
+ if (options['zoomOnClick'] != undefined) {
138
+ this.zoomOnClick_ = options['zoomOnClick'];
139
+ }
140
+
141
+ /**
142
+ * @type {boolean}
143
+ * @private
144
+ */
145
+ this.averageCenter_ = false;
146
+
147
+ if (options['averageCenter'] != undefined) {
148
+ this.averageCenter_ = options['averageCenter'];
149
+ }
150
+
151
+ this.setupStyles_();
152
+
153
+ this.setMap(map);
154
+
155
+ /**
156
+ * @type {number}
157
+ * @private
158
+ */
159
+ this.prevZoom_ = this.map_.getZoom();
160
+
161
+ // Add the map event listeners
162
+ var that = this;
163
+ google.maps.event.addListener(this.map_, 'zoom_changed', function() {
164
+ // Determines map type and prevent illegal zoom levels
165
+ var zoom = that.map_.getZoom();
166
+ var minZoom = that.map_.minZoom || 0;
167
+ var maxZoom = Math.min(that.map_.maxZoom || 100,
168
+ that.map_.mapTypes[that.map_.getMapTypeId()].maxZoom);
169
+ zoom = Math.min(Math.max(zoom,minZoom),maxZoom);
170
+
171
+ if (that.prevZoom_ != zoom) {
172
+ that.prevZoom_ = zoom;
173
+ that.resetViewport();
174
+ }
175
+ });
176
+
177
+ google.maps.event.addListener(this.map_, 'idle', function() {
178
+ that.redraw();
179
+ });
180
+
181
+ // Finally, add the markers
182
+ if (opt_markers && (opt_markers.length || Object.keys(opt_markers).length)) {
183
+ this.addMarkers(opt_markers, false);
184
+ }
185
+ }
186
+
187
+
188
+ /**
189
+ * The marker cluster image path.
190
+ *
191
+ * @type {string}
192
+ * @private
193
+ */
194
+ MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_PATH_ =
195
+ 'http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/' +
196
+ 'images/m';
197
+
198
+
199
+ /**
200
+ * The marker cluster image path.
201
+ *
202
+ * @type {string}
203
+ * @private
204
+ */
205
+ MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_EXTENSION_ = 'png';
206
+
207
+
208
+ /**
209
+ * Extends a objects prototype by anothers.
210
+ *
211
+ * @param {Object} obj1 The object to be extended.
212
+ * @param {Object} obj2 The object to extend with.
213
+ * @return {Object} The new extended object.
214
+ * @ignore
215
+ */
216
+ MarkerClusterer.prototype.extend = function(obj1, obj2) {
217
+ return (function(object) {
218
+ for (var property in object.prototype) {
219
+ this.prototype[property] = object.prototype[property];
220
+ }
221
+ return this;
222
+ }).apply(obj1, [obj2]);
223
+ };
224
+
225
+
226
+ /**
227
+ * Implementaion of the interface method.
228
+ * @ignore
229
+ */
230
+ MarkerClusterer.prototype.onAdd = function() {
231
+ this.setReady_(true);
232
+ };
233
+
234
+ /**
235
+ * Implementaion of the interface method.
236
+ * @ignore
237
+ */
238
+ MarkerClusterer.prototype.draw = function() {};
239
+
240
+ /**
241
+ * Sets up the styles object.
242
+ *
243
+ * @private
244
+ */
245
+ MarkerClusterer.prototype.setupStyles_ = function() {
246
+ if (this.styles_.length) {
247
+ return;
248
+ }
249
+
250
+ for (var i = 0, size; size = this.sizes[i]; i++) {
251
+ this.styles_.push({
252
+ url: this.imagePath_ + (i + 1) + '.' + this.imageExtension_,
253
+ height: size,
254
+ width: size
255
+ });
256
+ }
257
+ };
258
+
259
+ /**
260
+ * Fit the map to the bounds of the markers in the clusterer.
261
+ */
262
+ MarkerClusterer.prototype.fitMapToMarkers = function() {
263
+ var markers = this.getMarkers();
264
+ var bounds = new google.maps.LatLngBounds();
265
+ for (var i = 0, marker; marker = markers[i]; i++) {
266
+ bounds.extend(marker.getPosition());
267
+ }
268
+
269
+ this.map_.fitBounds(bounds);
270
+ };
271
+
272
+
273
+ /**
274
+ * Sets the styles.
275
+ *
276
+ * @param {Object} styles The style to set.
277
+ */
278
+ MarkerClusterer.prototype.setStyles = function(styles) {
279
+ this.styles_ = styles;
280
+ };
281
+
282
+
283
+ /**
284
+ * Gets the styles.
285
+ *
286
+ * @return {Object} The styles object.
287
+ */
288
+ MarkerClusterer.prototype.getStyles = function() {
289
+ return this.styles_;
290
+ };
291
+
292
+
293
+ /**
294
+ * Whether zoom on click is set.
295
+ *
296
+ * @return {boolean} True if zoomOnClick_ is set.
297
+ */
298
+ MarkerClusterer.prototype.isZoomOnClick = function() {
299
+ return this.zoomOnClick_;
300
+ };
301
+
302
+ /**
303
+ * Whether average center is set.
304
+ *
305
+ * @return {boolean} True if averageCenter_ is set.
306
+ */
307
+ MarkerClusterer.prototype.isAverageCenter = function() {
308
+ return this.averageCenter_;
309
+ };
310
+
311
+
312
+ /**
313
+ * Returns the array of markers in the clusterer.
314
+ *
315
+ * @return {Array.<google.maps.Marker>} The markers.
316
+ */
317
+ MarkerClusterer.prototype.getMarkers = function() {
318
+ return this.markers_;
319
+ };
320
+
321
+
322
+ /**
323
+ * Returns the number of markers in the clusterer
324
+ *
325
+ * @return {Number} The number of markers.
326
+ */
327
+ MarkerClusterer.prototype.getTotalMarkers = function() {
328
+ return this.markers_.length;
329
+ };
330
+
331
+
332
+ /**
333
+ * Sets the max zoom for the clusterer.
334
+ *
335
+ * @param {number} maxZoom The max zoom level.
336
+ */
337
+ MarkerClusterer.prototype.setMaxZoom = function(maxZoom) {
338
+ this.maxZoom_ = maxZoom;
339
+ };
340
+
341
+
342
+ /**
343
+ * Gets the max zoom for the clusterer.
344
+ *
345
+ * @return {number} The max zoom level.
346
+ */
347
+ MarkerClusterer.prototype.getMaxZoom = function() {
348
+ return this.maxZoom_;
349
+ };
350
+
351
+
352
+ /**
353
+ * The function for calculating the cluster icon image.
354
+ *
355
+ * @param {Array.<google.maps.Marker>} markers The markers in the clusterer.
356
+ * @param {number} numStyles The number of styles available.
357
+ * @return {Object} A object properties: 'text' (string) and 'index' (number).
358
+ * @private
359
+ */
360
+ MarkerClusterer.prototype.calculator_ = function(markers, numStyles) {
361
+ var index = 0;
362
+ var count = markers.length;
363
+ var dv = count;
364
+ while (dv !== 0) {
365
+ dv = parseInt(dv / 10, 10);
366
+ index++;
367
+ }
368
+
369
+ index = Math.min(index, numStyles);
370
+ return {
371
+ text: count,
372
+ index: index
373
+ };
374
+ };
375
+
376
+
377
+ /**
378
+ * Set the calculator function.
379
+ *
380
+ * @param {function(Array, number)} calculator The function to set as the
381
+ * calculator. The function should return a object properties:
382
+ * 'text' (string) and 'index' (number).
383
+ *
384
+ */
385
+ MarkerClusterer.prototype.setCalculator = function(calculator) {
386
+ this.calculator_ = calculator;
387
+ };
388
+
389
+
390
+ /**
391
+ * Get the calculator function.
392
+ *
393
+ * @return {function(Array, number)} the calculator function.
394
+ */
395
+ MarkerClusterer.prototype.getCalculator = function() {
396
+ return this.calculator_;
397
+ };
398
+
399
+
400
+ /**
401
+ * Add an array of markers to the clusterer.
402
+ *
403
+ * @param {Array.<google.maps.Marker>} markers The markers to add.
404
+ * @param {boolean=} opt_nodraw Whether to redraw the clusters.
405
+ */
406
+ MarkerClusterer.prototype.addMarkers = function(markers, opt_nodraw) {
407
+ if (markers.length) {
408
+ for (var i = 0, marker; marker = markers[i]; i++) {
409
+ this.pushMarkerTo_(marker);
410
+ }
411
+ } else if (Object.keys(markers).length) {
412
+ for (var marker in markers) {
413
+ this.pushMarkerTo_(markers[marker]);
414
+ }
415
+ }
416
+ if (!opt_nodraw) {
417
+ this.redraw();
418
+ }
419
+ };
420
+
421
+
422
+ /**
423
+ * Pushes a marker to the clusterer.
424
+ *
425
+ * @param {google.maps.Marker} marker The marker to add.
426
+ * @private
427
+ */
428
+ MarkerClusterer.prototype.pushMarkerTo_ = function(marker) {
429
+ marker.isAdded = false;
430
+ if (marker['draggable']) {
431
+ // If the marker is draggable add a listener so we update the clusters on
432
+ // the drag end.
433
+ var that = this;
434
+ google.maps.event.addListener(marker, 'dragend', function() {
435
+ marker.isAdded = false;
436
+ that.repaint();
437
+ });
438
+ }
439
+ this.markers_.push(marker);
440
+ };
441
+
442
+
443
+ /**
444
+ * Adds a marker to the clusterer and redraws if needed.
445
+ *
446
+ * @param {google.maps.Marker} marker The marker to add.
447
+ * @param {boolean=} opt_nodraw Whether to redraw the clusters.
448
+ */
449
+ MarkerClusterer.prototype.addMarker = function(marker, opt_nodraw) {
450
+ this.pushMarkerTo_(marker);
451
+ if (!opt_nodraw) {
452
+ this.redraw();
453
+ }
454
+ };
455
+
456
+
457
+ /**
458
+ * Removes a marker and returns true if removed, false if not
459
+ *
460
+ * @param {google.maps.Marker} marker The marker to remove
461
+ * @return {boolean} Whether the marker was removed or not
462
+ * @private
463
+ */
464
+ MarkerClusterer.prototype.removeMarker_ = function(marker) {
465
+ var index = -1;
466
+ if (this.markers_.indexOf) {
467
+ index = this.markers_.indexOf(marker);
468
+ } else {
469
+ for (var i = 0, m; m = this.markers_[i]; i++) {
470
+ if (m == marker) {
471
+ index = i;
472
+ break;
473
+ }
474
+ }
475
+ }
476
+
477
+ if (index == -1) {
478
+ // Marker is not in our list of markers.
479
+ return false;
480
+ }
481
+
482
+ marker.setMap(null);
483
+
484
+ this.markers_.splice(index, 1);
485
+
486
+ return true;
487
+ };
488
+
489
+
490
+ /**
491
+ * Remove a marker from the cluster.
492
+ *
493
+ * @param {google.maps.Marker} marker The marker to remove.
494
+ * @param {boolean=} opt_nodraw Optional boolean to force no redraw.
495
+ * @return {boolean} True if the marker was removed.
496
+ */
497
+ MarkerClusterer.prototype.removeMarker = function(marker, opt_nodraw) {
498
+ var removed = this.removeMarker_(marker);
499
+
500
+ if (!opt_nodraw && removed) {
501
+ this.resetViewport();
502
+ this.redraw();
503
+ return true;
504
+ } else {
505
+ return false;
506
+ }
507
+ };
508
+
509
+
510
+ /**
511
+ * Removes an array of markers from the cluster.
512
+ *
513
+ * @param {Array.<google.maps.Marker>} markers The markers to remove.
514
+ * @param {boolean=} opt_nodraw Optional boolean to force no redraw.
515
+ */
516
+ MarkerClusterer.prototype.removeMarkers = function(markers, opt_nodraw) {
517
+ var removed = false;
518
+
519
+ for (var i = 0, marker; marker = markers[i]; i++) {
520
+ var r = this.removeMarker_(marker);
521
+ removed = removed || r;
522
+ }
523
+
524
+ if (!opt_nodraw && removed) {
525
+ this.resetViewport();
526
+ this.redraw();
527
+ return true;
528
+ }
529
+ };
530
+
531
+
532
+ /**
533
+ * Sets the clusterer's ready state.
534
+ *
535
+ * @param {boolean} ready The state.
536
+ * @private
537
+ */
538
+ MarkerClusterer.prototype.setReady_ = function(ready) {
539
+ if (!this.ready_) {
540
+ this.ready_ = ready;
541
+ this.createClusters_();
542
+ }
543
+ };
544
+
545
+
546
+ /**
547
+ * Returns the number of clusters in the clusterer.
548
+ *
549
+ * @return {number} The number of clusters.
550
+ */
551
+ MarkerClusterer.prototype.getTotalClusters = function() {
552
+ return this.clusters_.length;
553
+ };
554
+
555
+
556
+ /**
557
+ * Returns the google map that the clusterer is associated with.
558
+ *
559
+ * @return {google.maps.Map} The map.
560
+ */
561
+ MarkerClusterer.prototype.getMap = function() {
562
+ return this.map_;
563
+ };
564
+
565
+
566
+ /**
567
+ * Sets the google map that the clusterer is associated with.
568
+ *
569
+ * @param {google.maps.Map} map The map.
570
+ */
571
+ MarkerClusterer.prototype.setMap = function(map) {
572
+ this.map_ = map;
573
+ };
574
+
575
+
576
+ /**
577
+ * Returns the size of the grid.
578
+ *
579
+ * @return {number} The grid size.
580
+ */
581
+ MarkerClusterer.prototype.getGridSize = function() {
582
+ return this.gridSize_;
583
+ };
584
+
585
+
586
+ /**
587
+ * Sets the size of the grid.
588
+ *
589
+ * @param {number} size The grid size.
590
+ */
591
+ MarkerClusterer.prototype.setGridSize = function(size) {
592
+ this.gridSize_ = size;
593
+ };
594
+
595
+
596
+ /**
597
+ * Returns the min cluster size.
598
+ *
599
+ * @return {number} The grid size.
600
+ */
601
+ MarkerClusterer.prototype.getMinClusterSize = function() {
602
+ return this.minClusterSize_;
603
+ };
604
+
605
+ /**
606
+ * Sets the min cluster size.
607
+ *
608
+ * @param {number} size The grid size.
609
+ */
610
+ MarkerClusterer.prototype.setMinClusterSize = function(size) {
611
+ this.minClusterSize_ = size;
612
+ };
613
+
614
+
615
+ /**
616
+ * Extends a bounds object by the grid size.
617
+ *
618
+ * @param {google.maps.LatLngBounds} bounds The bounds to extend.
619
+ * @return {google.maps.LatLngBounds} The extended bounds.
620
+ */
621
+ MarkerClusterer.prototype.getExtendedBounds = function(bounds) {
622
+ var projection = this.getProjection();
623
+
624
+ // Turn the bounds into latlng.
625
+ var tr = new google.maps.LatLng(bounds.getNorthEast().lat(),
626
+ bounds.getNorthEast().lng());
627
+ var bl = new google.maps.LatLng(bounds.getSouthWest().lat(),
628
+ bounds.getSouthWest().lng());
629
+
630
+ // Convert the points to pixels and the extend out by the grid size.
631
+ var trPix = projection.fromLatLngToDivPixel(tr);
632
+ trPix.x += this.gridSize_;
633
+ trPix.y -= this.gridSize_;
634
+
635
+ var blPix = projection.fromLatLngToDivPixel(bl);
636
+ blPix.x -= this.gridSize_;
637
+ blPix.y += this.gridSize_;
638
+
639
+ // Convert the pixel points back to LatLng
640
+ var ne = projection.fromDivPixelToLatLng(trPix);
641
+ var sw = projection.fromDivPixelToLatLng(blPix);
642
+
643
+ // Extend the bounds to contain the new bounds.
644
+ bounds.extend(ne);
645
+ bounds.extend(sw);
646
+
647
+ return bounds;
648
+ };
649
+
650
+
651
+ /**
652
+ * Determins if a marker is contained in a bounds.
653
+ *
654
+ * @param {google.maps.Marker} marker The marker to check.
655
+ * @param {google.maps.LatLngBounds} bounds The bounds to check against.
656
+ * @return {boolean} True if the marker is in the bounds.
657
+ * @private
658
+ */
659
+ MarkerClusterer.prototype.isMarkerInBounds_ = function(marker, bounds) {
660
+ return bounds.contains(marker.getPosition());
661
+ };
662
+
663
+
664
+ /**
665
+ * Clears all clusters and markers from the clusterer.
666
+ */
667
+ MarkerClusterer.prototype.clearMarkers = function() {
668
+ this.resetViewport(true);
669
+
670
+ // Set the markers a empty array.
671
+ this.markers_ = [];
672
+ };
673
+
674
+
675
+ /**
676
+ * Clears all existing clusters and recreates them.
677
+ * @param {boolean} opt_hide To also hide the marker.
678
+ */
679
+ MarkerClusterer.prototype.resetViewport = function(opt_hide) {
680
+ // Remove all the clusters
681
+ for (var i = 0, cluster; cluster = this.clusters_[i]; i++) {
682
+ cluster.remove();
683
+ }
684
+
685
+ // Reset the markers to not be added and to be invisible.
686
+ for (var i = 0, marker; marker = this.markers_[i]; i++) {
687
+ marker.isAdded = false;
688
+ if (opt_hide) {
689
+ marker.setMap(null);
690
+ }
691
+ }
692
+
693
+ this.clusters_ = [];
694
+ };
695
+
696
+ /**
697
+ *
698
+ */
699
+ MarkerClusterer.prototype.repaint = function() {
700
+ var oldClusters = this.clusters_.slice();
701
+ this.clusters_.length = 0;
702
+ this.resetViewport();
703
+ this.redraw();
704
+
705
+ // Remove the old clusters.
706
+ // Do it in a timeout so the other clusters have been drawn first.
707
+ window.setTimeout(function() {
708
+ for (var i = 0, cluster; cluster = oldClusters[i]; i++) {
709
+ cluster.remove();
710
+ }
711
+ }, 0);
712
+ };
713
+
714
+
715
+ /**
716
+ * Redraws the clusters.
717
+ */
718
+ MarkerClusterer.prototype.redraw = function() {
719
+ this.createClusters_();
720
+ };
721
+
722
+
723
+ /**
724
+ * Calculates the distance between two latlng locations in km.
725
+ * @see http://www.movable-type.co.uk/scripts/latlong.html
726
+ *
727
+ * @param {google.maps.LatLng} p1 The first lat lng point.
728
+ * @param {google.maps.LatLng} p2 The second lat lng point.
729
+ * @return {number} The distance between the two points in km.
730
+ * @private
731
+ */
732
+ MarkerClusterer.prototype.distanceBetweenPoints_ = function(p1, p2) {
733
+ if (!p1 || !p2) {
734
+ return 0;
735
+ }
736
+
737
+ var R = 6371; // Radius of the Earth in km
738
+ var dLat = (p2.lat() - p1.lat()) * Math.PI / 180;
739
+ var dLon = (p2.lng() - p1.lng()) * Math.PI / 180;
740
+ var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
741
+ Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) *
742
+ Math.sin(dLon / 2) * Math.sin(dLon / 2);
743
+ var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
744
+ var d = R * c;
745
+ return d;
746
+ };
747
+
748
+
749
+ /**
750
+ * Add a marker to a cluster, or creates a new cluster.
751
+ *
752
+ * @param {google.maps.Marker} marker The marker to add.
753
+ * @private
754
+ */
755
+ MarkerClusterer.prototype.addToClosestCluster_ = function(marker) {
756
+ var distance = 40000; // Some large number
757
+ var clusterToAddTo = null;
758
+ var pos = marker.getPosition();
759
+ for (var i = 0, cluster; cluster = this.clusters_[i]; i++) {
760
+ var center = cluster.getCenter();
761
+ if (center) {
762
+ var d = this.distanceBetweenPoints_(center, marker.getPosition());
763
+ if (d < distance) {
764
+ distance = d;
765
+ clusterToAddTo = cluster;
766
+ }
767
+ }
768
+ }
769
+
770
+ if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) {
771
+ clusterToAddTo.addMarker(marker);
772
+ } else {
773
+ var cluster = new Cluster(this);
774
+ cluster.addMarker(marker);
775
+ this.clusters_.push(cluster);
776
+ }
777
+ };
778
+
779
+
780
+ /**
781
+ * Creates the clusters.
782
+ *
783
+ * @private
784
+ */
785
+ MarkerClusterer.prototype.createClusters_ = function() {
786
+ if (!this.ready_) {
787
+ return;
788
+ }
789
+
790
+ // Get our current map view bounds.
791
+ // Create a new bounds object so we don't affect the map.
792
+ var mapBounds = new google.maps.LatLngBounds(this.map_.getBounds().getSouthWest(),
793
+ this.map_.getBounds().getNorthEast());
794
+ var bounds = this.getExtendedBounds(mapBounds);
795
+
796
+ for (var i = 0, marker; marker = this.markers_[i]; i++) {
797
+ if (!marker.isAdded && this.isMarkerInBounds_(marker, bounds)) {
798
+ this.addToClosestCluster_(marker);
799
+ }
800
+ }
801
+ };
802
+
803
+
804
+ /**
805
+ * A cluster that contains markers.
806
+ *
807
+ * @param {MarkerClusterer} markerClusterer The markerclusterer that this
808
+ * cluster is associated with.
809
+ * @constructor
810
+ * @ignore
811
+ */
812
+ function Cluster(markerClusterer) {
813
+ this.markerClusterer_ = markerClusterer;
814
+ this.map_ = markerClusterer.getMap();
815
+ this.gridSize_ = markerClusterer.getGridSize();
816
+ this.minClusterSize_ = markerClusterer.getMinClusterSize();
817
+ this.averageCenter_ = markerClusterer.isAverageCenter();
818
+ this.center_ = null;
819
+ this.markers_ = [];
820
+ this.bounds_ = null;
821
+ this.clusterIcon_ = new ClusterIcon(this, markerClusterer.getStyles(),
822
+ markerClusterer.getGridSize());
823
+ }
824
+
825
+ /**
826
+ * Determins if a marker is already added to the cluster.
827
+ *
828
+ * @param {google.maps.Marker} marker The marker to check.
829
+ * @return {boolean} True if the marker is already added.
830
+ */
831
+ Cluster.prototype.isMarkerAlreadyAdded = function(marker) {
832
+ if (this.markers_.indexOf) {
833
+ return this.markers_.indexOf(marker) != -1;
834
+ } else {
835
+ for (var i = 0, m; m = this.markers_[i]; i++) {
836
+ if (m == marker) {
837
+ return true;
838
+ }
839
+ }
840
+ }
841
+ return false;
842
+ };
843
+
844
+
845
+ /**
846
+ * Add a marker the cluster.
847
+ *
848
+ * @param {google.maps.Marker} marker The marker to add.
849
+ * @return {boolean} True if the marker was added.
850
+ */
851
+ Cluster.prototype.addMarker = function(marker) {
852
+ if (this.isMarkerAlreadyAdded(marker)) {
853
+ return false;
854
+ }
855
+
856
+ if (!this.center_) {
857
+ this.center_ = marker.getPosition();
858
+ this.calculateBounds_();
859
+ } else {
860
+ if (this.averageCenter_) {
861
+ var l = this.markers_.length + 1;
862
+ var lat = (this.center_.lat() * (l-1) + marker.getPosition().lat()) / l;
863
+ var lng = (this.center_.lng() * (l-1) + marker.getPosition().lng()) / l;
864
+ this.center_ = new google.maps.LatLng(lat, lng);
865
+ this.calculateBounds_();
866
+ }
867
+ }
868
+
869
+ marker.isAdded = true;
870
+ this.markers_.push(marker);
871
+
872
+ var len = this.markers_.length;
873
+ if (len < this.minClusterSize_ && marker.getMap() != this.map_) {
874
+ // Min cluster size not reached so show the marker.
875
+ marker.setMap(this.map_);
876
+ }
877
+
878
+ if (len == this.minClusterSize_) {
879
+ // Hide the markers that were showing.
880
+ for (var i = 0; i < len; i++) {
881
+ this.markers_[i].setMap(null);
882
+ }
883
+ }
884
+
885
+ if (len >= this.minClusterSize_) {
886
+ marker.setMap(null);
887
+ }
888
+
889
+ this.updateIcon();
890
+ return true;
891
+ };
892
+
893
+
894
+ /**
895
+ * Returns the marker clusterer that the cluster is associated with.
896
+ *
897
+ * @return {MarkerClusterer} The associated marker clusterer.
898
+ */
899
+ Cluster.prototype.getMarkerClusterer = function() {
900
+ return this.markerClusterer_;
901
+ };
902
+
903
+
904
+ /**
905
+ * Returns the bounds of the cluster.
906
+ *
907
+ * @return {google.maps.LatLngBounds} the cluster bounds.
908
+ */
909
+ Cluster.prototype.getBounds = function() {
910
+ var bounds = new google.maps.LatLngBounds(this.center_, this.center_);
911
+ var markers = this.getMarkers();
912
+ for (var i = 0, marker; marker = markers[i]; i++) {
913
+ bounds.extend(marker.getPosition());
914
+ }
915
+ return bounds;
916
+ };
917
+
918
+
919
+ /**
920
+ * Removes the cluster
921
+ */
922
+ Cluster.prototype.remove = function() {
923
+ this.clusterIcon_.remove();
924
+ this.markers_.length = 0;
925
+ delete this.markers_;
926
+ };
927
+
928
+
929
+ /**
930
+ * Returns the center of the cluster.
931
+ *
932
+ * @return {number} The cluster center.
933
+ */
934
+ Cluster.prototype.getSize = function() {
935
+ return this.markers_.length;
936
+ };
937
+
938
+
939
+ /**
940
+ * Returns the center of the cluster.
941
+ *
942
+ * @return {Array.<google.maps.Marker>} The cluster center.
943
+ */
944
+ Cluster.prototype.getMarkers = function() {
945
+ return this.markers_;
946
+ };
947
+
948
+
949
+ /**
950
+ * Returns the center of the cluster.
951
+ *
952
+ * @return {google.maps.LatLng} The cluster center.
953
+ */
954
+ Cluster.prototype.getCenter = function() {
955
+ return this.center_;
956
+ };
957
+
958
+
959
+ /**
960
+ * Calculated the extended bounds of the cluster with the grid.
961
+ *
962
+ * @private
963
+ */
964
+ Cluster.prototype.calculateBounds_ = function() {
965
+ var bounds = new google.maps.LatLngBounds(this.center_, this.center_);
966
+ this.bounds_ = this.markerClusterer_.getExtendedBounds(bounds);
967
+ };
968
+
969
+
970
+ /**
971
+ * Determines if a marker lies in the clusters bounds.
972
+ *
973
+ * @param {google.maps.Marker} marker The marker to check.
974
+ * @return {boolean} True if the marker lies in the bounds.
975
+ */
976
+ Cluster.prototype.isMarkerInClusterBounds = function(marker) {
977
+ return this.bounds_.contains(marker.getPosition());
978
+ };
979
+
980
+
981
+ /**
982
+ * Returns the map that the cluster is associated with.
983
+ *
984
+ * @return {google.maps.Map} The map.
985
+ */
986
+ Cluster.prototype.getMap = function() {
987
+ return this.map_;
988
+ };
989
+
990
+
991
+ /**
992
+ * Updates the cluster icon
993
+ */
994
+ Cluster.prototype.updateIcon = function() {
995
+ var zoom = this.map_.getZoom();
996
+ var mz = this.markerClusterer_.getMaxZoom();
997
+
998
+ if (mz && zoom > mz) {
999
+ // The zoom is greater than our max zoom so show all the markers in cluster.
1000
+ for (var i = 0, marker; marker = this.markers_[i]; i++) {
1001
+ marker.setMap(this.map_);
1002
+ }
1003
+ return;
1004
+ }
1005
+
1006
+ if (this.markers_.length < this.minClusterSize_) {
1007
+ // Min cluster size not yet reached.
1008
+ this.clusterIcon_.hide();
1009
+ return;
1010
+ }
1011
+
1012
+ var numStyles = this.markerClusterer_.getStyles().length;
1013
+ var sums = this.markerClusterer_.getCalculator()(this.markers_, numStyles);
1014
+ this.clusterIcon_.setCenter(this.center_);
1015
+ this.clusterIcon_.setSums(sums);
1016
+ this.clusterIcon_.show();
1017
+ };
1018
+
1019
+
1020
+ /**
1021
+ * A cluster icon
1022
+ *
1023
+ * @param {Cluster} cluster The cluster to be associated with.
1024
+ * @param {Object} styles An object that has style properties:
1025
+ * 'url': (string) The image url.
1026
+ * 'height': (number) The image height.
1027
+ * 'width': (number) The image width.
1028
+ * 'anchor': (Array) The anchor position of the label text.
1029
+ * 'textColor': (string) The text color.
1030
+ * 'textSize': (number) The text size.
1031
+ * 'backgroundPosition: (string) The background postition x, y.
1032
+ * @param {number=} opt_padding Optional padding to apply to the cluster icon.
1033
+ * @constructor
1034
+ * @extends google.maps.OverlayView
1035
+ * @ignore
1036
+ */
1037
+ function ClusterIcon(cluster, styles, opt_padding) {
1038
+ cluster.getMarkerClusterer().extend(ClusterIcon, google.maps.OverlayView);
1039
+
1040
+ this.styles_ = styles;
1041
+ this.padding_ = opt_padding || 0;
1042
+ this.cluster_ = cluster;
1043
+ this.center_ = null;
1044
+ this.map_ = cluster.getMap();
1045
+ this.div_ = null;
1046
+ this.sums_ = null;
1047
+ this.visible_ = false;
1048
+
1049
+ this.setMap(this.map_);
1050
+ }
1051
+
1052
+
1053
+ /**
1054
+ * Triggers the clusterclick event and zoom's if the option is set.
1055
+ */
1056
+ ClusterIcon.prototype.triggerClusterClick = function() {
1057
+ var markerClusterer = this.cluster_.getMarkerClusterer();
1058
+
1059
+ // Trigger the clusterclick event.
1060
+ google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster_);
1061
+
1062
+ if (markerClusterer.isZoomOnClick()) {
1063
+ // Zoom into the cluster.
1064
+ this.map_.fitBounds(this.cluster_.getBounds());
1065
+ }
1066
+ };
1067
+
1068
+
1069
+ /**
1070
+ * Adding the cluster icon to the dom.
1071
+ * @ignore
1072
+ */
1073
+ ClusterIcon.prototype.onAdd = function() {
1074
+ this.div_ = document.createElement('DIV');
1075
+ if (this.visible_) {
1076
+ var pos = this.getPosFromLatLng_(this.center_);
1077
+ this.div_.style.cssText = this.createCss(pos);
1078
+ this.div_.innerHTML = this.sums_.text;
1079
+ }
1080
+
1081
+ var panes = this.getPanes();
1082
+ panes.overlayMouseTarget.appendChild(this.div_);
1083
+
1084
+ var that = this;
1085
+ google.maps.event.addDomListener(this.div_, 'click', function() {
1086
+ that.triggerClusterClick();
1087
+ });
1088
+ };
1089
+
1090
+
1091
+ /**
1092
+ * Returns the position to place the div dending on the latlng.
1093
+ *
1094
+ * @param {google.maps.LatLng} latlng The position in latlng.
1095
+ * @return {google.maps.Point} The position in pixels.
1096
+ * @private
1097
+ */
1098
+ ClusterIcon.prototype.getPosFromLatLng_ = function(latlng) {
1099
+ var pos = this.getProjection().fromLatLngToDivPixel(latlng);
1100
+ pos.x -= parseInt(this.width_ / 2, 10);
1101
+ pos.y -= parseInt(this.height_ / 2, 10);
1102
+ return pos;
1103
+ };
1104
+
1105
+
1106
+ /**
1107
+ * Draw the icon.
1108
+ * @ignore
1109
+ */
1110
+ ClusterIcon.prototype.draw = function() {
1111
+ if (this.visible_) {
1112
+ var pos = this.getPosFromLatLng_(this.center_);
1113
+ this.div_.style.top = pos.y + 'px';
1114
+ this.div_.style.left = pos.x + 'px';
1115
+ }
1116
+ };
1117
+
1118
+
1119
+ /**
1120
+ * Hide the icon.
1121
+ */
1122
+ ClusterIcon.prototype.hide = function() {
1123
+ if (this.div_) {
1124
+ this.div_.style.display = 'none';
1125
+ }
1126
+ this.visible_ = false;
1127
+ };
1128
+
1129
+
1130
+ /**
1131
+ * Position and show the icon.
1132
+ */
1133
+ ClusterIcon.prototype.show = function() {
1134
+ if (this.div_) {
1135
+ var pos = this.getPosFromLatLng_(this.center_);
1136
+ this.div_.style.cssText = this.createCss(pos);
1137
+ this.div_.style.display = '';
1138
+ }
1139
+ this.visible_ = true;
1140
+ };
1141
+
1142
+
1143
+ /**
1144
+ * Remove the icon from the map
1145
+ */
1146
+ ClusterIcon.prototype.remove = function() {
1147
+ this.setMap(null);
1148
+ };
1149
+
1150
+
1151
+ /**
1152
+ * Implementation of the onRemove interface.
1153
+ * @ignore
1154
+ */
1155
+ ClusterIcon.prototype.onRemove = function() {
1156
+ if (this.div_ && this.div_.parentNode) {
1157
+ this.hide();
1158
+ this.div_.parentNode.removeChild(this.div_);
1159
+ this.div_ = null;
1160
+ }
1161
+ };
1162
+
1163
+
1164
+ /**
1165
+ * Set the sums of the icon.
1166
+ *
1167
+ * @param {Object} sums The sums containing:
1168
+ * 'text': (string) The text to display in the icon.
1169
+ * 'index': (number) The style index of the icon.
1170
+ */
1171
+ ClusterIcon.prototype.setSums = function(sums) {
1172
+ this.sums_ = sums;
1173
+ this.text_ = sums.text;
1174
+ this.index_ = sums.index;
1175
+ if (this.div_) {
1176
+ this.div_.innerHTML = sums.text;
1177
+ }
1178
+
1179
+ this.useStyle();
1180
+ };
1181
+
1182
+
1183
+ /**
1184
+ * Sets the icon to the the styles.
1185
+ */
1186
+ ClusterIcon.prototype.useStyle = function() {
1187
+ var index = Math.max(0, this.sums_.index - 1);
1188
+ index = Math.min(this.styles_.length - 1, index);
1189
+ var style = this.styles_[index];
1190
+ this.url_ = style['url'];
1191
+ this.height_ = style['height'];
1192
+ this.width_ = style['width'];
1193
+ this.textColor_ = style['textColor'];
1194
+ this.anchor_ = style['anchor'];
1195
+ this.textSize_ = style['textSize'];
1196
+ this.backgroundPosition_ = style['backgroundPosition'];
1197
+ };
1198
+
1199
+
1200
+ /**
1201
+ * Sets the center of the icon.
1202
+ *
1203
+ * @param {google.maps.LatLng} center The latlng to set as the center.
1204
+ */
1205
+ ClusterIcon.prototype.setCenter = function(center) {
1206
+ this.center_ = center;
1207
+ };
1208
+
1209
+
1210
+ /**
1211
+ * Create the css text based on the position of the icon.
1212
+ *
1213
+ * @param {google.maps.Point} pos The position.
1214
+ * @return {string} The css style text.
1215
+ */
1216
+ ClusterIcon.prototype.createCss = function(pos) {
1217
+ var style = [];
1218
+ style.push('background-image:url(' + this.url_ + ');');
1219
+ var backgroundPosition = this.backgroundPosition_ ? this.backgroundPosition_ : '0 0';
1220
+ style.push('background-position:' + backgroundPosition + ';');
1221
+
1222
+ if (typeof this.anchor_ === 'object') {
1223
+ if (typeof this.anchor_[0] === 'number' && this.anchor_[0] > 0 &&
1224
+ this.anchor_[0] < this.height_) {
1225
+ style.push('height:' + (this.height_ - this.anchor_[0]) +
1226
+ 'px; padding-top:' + this.anchor_[0] + 'px;');
1227
+ } else {
1228
+ style.push('height:' + this.height_ + 'px; line-height:' + this.height_ +
1229
+ 'px;');
1230
+ }
1231
+ if (typeof this.anchor_[1] === 'number' && this.anchor_[1] > 0 &&
1232
+ this.anchor_[1] < this.width_) {
1233
+ style.push('width:' + (this.width_ - this.anchor_[1]) +
1234
+ 'px; padding-left:' + this.anchor_[1] + 'px;');
1235
+ } else {
1236
+ style.push('width:' + this.width_ + 'px; text-align:center;');
1237
+ }
1238
+ } else {
1239
+ style.push('height:' + this.height_ + 'px; line-height:' +
1240
+ this.height_ + 'px; width:' + this.width_ + 'px; text-align:center;');
1241
+ }
1242
+
1243
+ var txtColor = this.textColor_ ? this.textColor_ : 'black';
1244
+ var txtSize = this.textSize_ ? this.textSize_ : 11;
1245
+
1246
+ style.push('cursor:pointer; top:' + pos.y + 'px; left:' +
1247
+ pos.x + 'px; color:' + txtColor + '; position:absolute; font-size:' +
1248
+ txtSize + 'px; font-family:Arial,sans-serif; font-weight:bold');
1249
+ return style.join('');
1250
+ };
1251
+
1252
+
1253
+ // Export Symbols for Closure
1254
+ // If you are not going to compile with closure then you can remove the
1255
+ // code below.
1256
+ window['MarkerClusterer'] = MarkerClusterer;
1257
+ MarkerClusterer.prototype['addMarker'] = MarkerClusterer.prototype.addMarker;
1258
+ MarkerClusterer.prototype['addMarkers'] = MarkerClusterer.prototype.addMarkers;
1259
+ MarkerClusterer.prototype['clearMarkers'] =
1260
+ MarkerClusterer.prototype.clearMarkers;
1261
+ MarkerClusterer.prototype['fitMapToMarkers'] =
1262
+ MarkerClusterer.prototype.fitMapToMarkers;
1263
+ MarkerClusterer.prototype['getCalculator'] =
1264
+ MarkerClusterer.prototype.getCalculator;
1265
+ MarkerClusterer.prototype['getGridSize'] =
1266
+ MarkerClusterer.prototype.getGridSize;
1267
+ MarkerClusterer.prototype['getExtendedBounds'] =
1268
+ MarkerClusterer.prototype.getExtendedBounds;
1269
+ MarkerClusterer.prototype['getMap'] = MarkerClusterer.prototype.getMap;
1270
+ MarkerClusterer.prototype['getMarkers'] = MarkerClusterer.prototype.getMarkers;
1271
+ MarkerClusterer.prototype['getMaxZoom'] = MarkerClusterer.prototype.getMaxZoom;
1272
+ MarkerClusterer.prototype['getStyles'] = MarkerClusterer.prototype.getStyles;
1273
+ MarkerClusterer.prototype['getTotalClusters'] =
1274
+ MarkerClusterer.prototype.getTotalClusters;
1275
+ MarkerClusterer.prototype['getTotalMarkers'] =
1276
+ MarkerClusterer.prototype.getTotalMarkers;
1277
+ MarkerClusterer.prototype['redraw'] = MarkerClusterer.prototype.redraw;
1278
+ MarkerClusterer.prototype['removeMarker'] =
1279
+ MarkerClusterer.prototype.removeMarker;
1280
+ MarkerClusterer.prototype['removeMarkers'] =
1281
+ MarkerClusterer.prototype.removeMarkers;
1282
+ MarkerClusterer.prototype['resetViewport'] =
1283
+ MarkerClusterer.prototype.resetViewport;
1284
+ MarkerClusterer.prototype['repaint'] =
1285
+ MarkerClusterer.prototype.repaint;
1286
+ MarkerClusterer.prototype['setCalculator'] =
1287
+ MarkerClusterer.prototype.setCalculator;
1288
+ MarkerClusterer.prototype['setGridSize'] =
1289
+ MarkerClusterer.prototype.setGridSize;
1290
+ MarkerClusterer.prototype['setMaxZoom'] =
1291
+ MarkerClusterer.prototype.setMaxZoom;
1292
+ MarkerClusterer.prototype['onAdd'] = MarkerClusterer.prototype.onAdd;
1293
+ MarkerClusterer.prototype['draw'] = MarkerClusterer.prototype.draw;
1294
+
1295
+ Cluster.prototype['getCenter'] = Cluster.prototype.getCenter;
1296
+ Cluster.prototype['getSize'] = Cluster.prototype.getSize;
1297
+ Cluster.prototype['getMarkers'] = Cluster.prototype.getMarkers;
1298
+
1299
+ ClusterIcon.prototype['onAdd'] = ClusterIcon.prototype.onAdd;
1300
+ ClusterIcon.prototype['draw'] = ClusterIcon.prototype.draw;
1301
+ ClusterIcon.prototype['onRemove'] = ClusterIcon.prototype.onRemove;
1302
+
1303
+ Object.keys = Object.keys || function(o) {
1304
+ var result = [];
1305
+ for(var name in o) {
1306
+ if (o.hasOwnProperty(name))
1307
+ result.push(name);
1308
+ }
1309
+ return result;
1310
+ };
js/markerclusterer.min.js ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function d(a){return function(b){this[a]=b}}function f(a){return function(){return this[a]}}var k;
2
+ function l(a,b,c){this.extend(l,google.maps.OverlayView);this.b=a;this.a=[];this.f=[];this.da=[53,56,66,78,90];this.j=[];this.A=!1;c=c||{};this.g=c.gridSize||60;this.l=c.minimumClusterSize||2;this.K=c.maxZoom||null;this.j=c.styles||[];this.Y=c.imagePath||this.R;this.X=c.imageExtension||this.Q;this.P=!0;void 0!=c.zoomOnClick&&(this.P=c.zoomOnClick);this.r=!1;void 0!=c.averageCenter&&(this.r=c.averageCenter);m(this);this.setMap(a);this.L=this.b.getZoom();var e=this;google.maps.event.addListener(this.b,
3
+ "zoom_changed",function(){var a=e.b.getZoom(),b=e.b.minZoom||0,c=Math.min(e.b.maxZoom||100,e.b.mapTypes[e.b.getMapTypeId()].maxZoom),a=Math.min(Math.max(a,b),c);e.L!=a&&(e.L=a,e.m())});google.maps.event.addListener(this.b,"idle",function(){e.i()});b&&(b.length||Object.keys(b).length)&&this.C(b,!1)}k=l.prototype;k.R="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m";k.Q="png";
4
+ k.extend=function(a,b){return function(a){for(var b in a.prototype)this.prototype[b]=a.prototype[b];return this}.apply(a,[b])};k.onAdd=function(){this.A||(this.A=!0,p(this))};k.draw=function(){};function m(a){if(!a.j.length)for(var b=0,c;c=a.da[b];b++)a.j.push({url:a.Y+(b+1)+"."+a.X,height:c,width:c})}k.T=function(){for(var a=this.o(),b=new google.maps.LatLngBounds,c=0,e;e=a[c];c++)b.extend(e.getPosition());this.b.fitBounds(b)};k.w=f("j");k.o=f("a");k.W=function(){return this.a.length};k.ca=d("K");
5
+ k.J=f("K");k.G=function(a,b){for(var c=0,e=a.length,g=e;0!==g;)g=parseInt(g/10,10),c++;c=Math.min(c,b);return{text:e,index:c}};k.aa=d("G");k.H=f("G");k.C=function(a,b){if(a.length)for(var c=0,e;e=a[c];c++)s(this,e);else if(Object.keys(a).length)for(e in a)s(this,a[e]);b||this.i()};function s(a,b){b.s=!1;b.draggable&&google.maps.event.addListener(b,"dragend",function(){b.s=!1;a.M()});a.a.push(b)}k.q=function(a,b){s(this,a);b||this.i()};
6
+ function t(a,b){var c=-1;if(a.a.indexOf)c=a.a.indexOf(b);else for(var e=0,g;g=a.a[e];e++)if(g==b){c=e;break}if(-1==c)return!1;b.setMap(null);a.a.splice(c,1);return!0}k.Z=function(a,b){var c=t(this,a);return!b&&c?(this.m(),this.i(),!0):!1};k.$=function(a,b){for(var c=!1,e=0,g;g=a[e];e++)g=t(this,g),c=c||g;if(!b&&c)return this.m(),this.i(),!0};k.V=function(){return this.f.length};k.getMap=f("b");k.setMap=d("b");k.I=f("g");k.ba=d("g");
7
+ k.v=function(a){var b=this.getProjection(),c=new google.maps.LatLng(a.getNorthEast().lat(),a.getNorthEast().lng()),e=new google.maps.LatLng(a.getSouthWest().lat(),a.getSouthWest().lng()),c=b.fromLatLngToDivPixel(c);c.x+=this.g;c.y-=this.g;e=b.fromLatLngToDivPixel(e);e.x-=this.g;e.y+=this.g;c=b.fromDivPixelToLatLng(c);b=b.fromDivPixelToLatLng(e);a.extend(c);a.extend(b);return a};k.S=function(){this.m(!0);this.a=[]};
8
+ k.m=function(a){for(var b=0,c;c=this.f[b];b++)c.remove();for(b=0;c=this.a[b];b++)c.s=!1,a&&c.setMap(null);this.f=[]};k.M=function(){var a=this.f.slice();this.f.length=0;this.m();this.i();window.setTimeout(function(){for(var b=0,c;c=a[b];b++)c.remove()},0)};k.i=function(){p(this)};
9
+ function p(a){if(a.A)for(var b=new google.maps.LatLngBounds(a.b.getBounds().getSouthWest(),a.b.getBounds().getNorthEast()),b=a.v(b),c=0,e;e=a.a[c];c++)if(!e.s&&b.contains(e.getPosition())){for(var g=a,u=4E4,q=null,x=0,n=void 0;n=g.f[x];x++){var h=n.getCenter();if(h){var r=e.getPosition();if(h&&r)var y=(r.lat()-h.lat())*Math.PI/180,z=(r.lng()-h.lng())*Math.PI/180,h=Math.sin(y/2)*Math.sin(y/2)+Math.cos(h.lat()*Math.PI/180)*Math.cos(r.lat()*Math.PI/180)*Math.sin(z/2)*Math.sin(z/2),h=12742*Math.atan2(Math.sqrt(h),
10
+ Math.sqrt(1-h));else h=0;h<u&&(u=h,q=n)}}q&&q.F.contains(e.getPosition())?q.q(e):(n=new v(g),n.q(e),g.f.push(n))}}function v(a){this.k=a;this.b=a.getMap();this.g=a.I();this.l=a.l;this.r=a.r;this.d=null;this.a=[];this.F=null;this.n=new w(this,a.w())}k=v.prototype;
11
+ k.q=function(a){var b;a:if(this.a.indexOf)b=-1!=this.a.indexOf(a);else{b=0;for(var c;c=this.a[b];b++)if(c==a){b=!0;break a}b=!1}if(b)return!1;this.d?this.r&&(c=this.a.length+1,b=(this.d.lat()*(c-1)+a.getPosition().lat())/c,c=(this.d.lng()*(c-1)+a.getPosition().lng())/c,this.d=new google.maps.LatLng(b,c),A(this)):(this.d=a.getPosition(),A(this));a.s=!0;this.a.push(a);b=this.a.length;b<this.l&&a.getMap()!=this.b&&a.setMap(this.b);if(b==this.l)for(c=0;c<b;c++)this.a[c].setMap(null);b>=this.l&&a.setMap(null);
12
+ a=this.b.getZoom();if((b=this.k.J())&&a>b)for(a=0;b=this.a[a];a++)b.setMap(this.b);else this.a.length<this.l?B(this.n):(b=this.k.H()(this.a,this.k.w().length),this.n.setCenter(this.d),a=this.n,a.B=b,a.c&&(a.c.innerHTML=b.text),b=Math.max(0,a.B.index-1),b=Math.min(a.j.length-1,b),b=a.j[b],a.ea=b.url,a.h=b.height,a.p=b.width,a.N=b.textColor,a.e=b.anchor,a.O=b.textSize,a.D=b.backgroundPosition,this.n.show());return!0};
13
+ k.getBounds=function(){for(var a=new google.maps.LatLngBounds(this.d,this.d),b=this.o(),c=0,e;e=b[c];c++)a.extend(e.getPosition());return a};k.remove=function(){this.n.remove();this.a.length=0;delete this.a};k.U=function(){return this.a.length};k.o=f("a");k.getCenter=f("d");function A(a){var b=new google.maps.LatLngBounds(a.d,a.d);a.F=a.k.v(b)}k.getMap=f("b");
14
+ function w(a,b){a.k.extend(w,google.maps.OverlayView);this.j=b;this.u=a;this.d=null;this.b=a.getMap();this.B=this.c=null;this.t=!1;this.setMap(this.b)}k=w.prototype;
15
+ k.onAdd=function(){this.c=document.createElement("DIV");if(this.t){var a=C(this,this.d);this.c.style.cssText=D(this,a);this.c.innerHTML=this.B.text}this.getPanes().overlayMouseTarget.appendChild(this.c);var b=this;google.maps.event.addDomListener(this.c,"click",function(){var a=b.u.k;google.maps.event.trigger(a,"clusterclick",b.u);a.P&&b.b.fitBounds(b.u.getBounds())})};function C(a,b){var c=a.getProjection().fromLatLngToDivPixel(b);c.x-=parseInt(a.p/2,10);c.y-=parseInt(a.h/2,10);return c}
16
+ k.draw=function(){if(this.t){var a=C(this,this.d);this.c.style.top=a.y+"px";this.c.style.left=a.x+"px"}};function B(a){a.c&&(a.c.style.display="none");a.t=!1}k.show=function(){if(this.c){var a=C(this,this.d);this.c.style.cssText=D(this,a);this.c.style.display=""}this.t=!0};k.remove=function(){this.setMap(null)};k.onRemove=function(){this.c&&this.c.parentNode&&(B(this),this.c.parentNode.removeChild(this.c),this.c=null)};k.setCenter=d("d");
17
+ function D(a,b){var c=[];c.push("background-image:url("+a.ea+");");c.push("background-position:"+(a.D?a.D:"0 0")+";");"object"===typeof a.e?("number"===typeof a.e[0]&&0<a.e[0]&&a.e[0]<a.h?c.push("height:"+(a.h-a.e[0])+"px; padding-top:"+a.e[0]+"px;"):c.push("height:"+a.h+"px; line-height:"+a.h+"px;"),"number"===typeof a.e[1]&&0<a.e[1]&&a.e[1]<a.p?c.push("width:"+(a.p-a.e[1])+"px; padding-left:"+a.e[1]+"px;"):c.push("width:"+a.p+"px; text-align:center;")):c.push("height:"+a.h+"px; line-height:"+a.h+
18
+ "px; width:"+a.p+"px; text-align:center;");c.push("cursor:pointer; top:"+b.y+"px; left:"+b.x+"px; color:"+(a.N?a.N:"black")+"; position:absolute; font-size:"+(a.O?a.O:11)+"px; font-family:Arial,sans-serif; font-weight:bold");return c.join("")}window.MarkerClusterer=l;l.prototype.addMarker=l.prototype.q;l.prototype.addMarkers=l.prototype.C;l.prototype.clearMarkers=l.prototype.S;l.prototype.fitMapToMarkers=l.prototype.T;l.prototype.getCalculator=l.prototype.H;l.prototype.getGridSize=l.prototype.I;
19
+ l.prototype.getExtendedBounds=l.prototype.v;l.prototype.getMap=l.prototype.getMap;l.prototype.getMarkers=l.prototype.o;l.prototype.getMaxZoom=l.prototype.J;l.prototype.getStyles=l.prototype.w;l.prototype.getTotalClusters=l.prototype.V;l.prototype.getTotalMarkers=l.prototype.W;l.prototype.redraw=l.prototype.i;l.prototype.removeMarker=l.prototype.Z;l.prototype.removeMarkers=l.prototype.$;l.prototype.resetViewport=l.prototype.m;l.prototype.repaint=l.prototype.M;l.prototype.setCalculator=l.prototype.aa;
20
+ l.prototype.setGridSize=l.prototype.ba;l.prototype.setMaxZoom=l.prototype.ca;l.prototype.onAdd=l.prototype.onAdd;l.prototype.draw=l.prototype.draw;v.prototype.getCenter=v.prototype.getCenter;v.prototype.getSize=v.prototype.U;v.prototype.getMarkers=v.prototype.o;w.prototype.onAdd=w.prototype.onAdd;w.prototype.draw=w.prototype.draw;w.prototype.onRemove=w.prototype.onRemove;Object.keys=Object.keys||function(a){var b=[],c;for(c in a)a.hasOwnProperty(c)&&b.push(c);return b};
21
+
js/wpsl-gmap.js CHANGED
@@ -1,15 +1,17 @@
1
  jQuery( document ).ready( function( $ ) {
2
- var geocoder, map, infowindow, directionsDisplay, directionsService, geolocationLatlng,
3
  markersArray = [],
 
4
  mapDefaults = {},
5
  resetMap = false,
 
6
  startMarkerData,
7
  startAddress,
8
  startLatLng,
9
  autoLoad = wpslSettings.autoLoad,
10
  $selects = $( "#wpsl-search-wrap select" );
11
 
12
- /* Load Google Maps */
13
  function initializeGmap() {
14
  var myOptions, zoomControlPosition, zoomControlStyle,
15
  latLng, zoomLevel, mapType,
@@ -17,18 +19,16 @@ function initializeGmap() {
17
 
18
  /* If no zoom location is defined, we show the entire world */
19
  if ( wpslSettings.zoomLatlng !== '' ) {
20
- latLng = wpslSettings.zoomLatlng.split( ',' );
21
  startLatLng = new google.maps.LatLng( latLng[0], latLng[1] );
22
- zoomLevel = parseInt( wpslSettings.zoomLevel );
23
  } else {
24
  startLatLng = new google.maps.LatLng( 0,0 );
25
- zoomLevel = 1;
26
  }
27
 
28
- geocoder = new google.maps.Geocoder();
29
- infowindow = new google.maps.InfoWindow({
30
- pixelOffset: new google.maps.Size( -12,0 ) //make the offset equal to the marker anchor, line 387
31
- });
32
  directionsDisplay = new google.maps.DirectionsRenderer();
33
  directionsService = new google.maps.DirectionsService();
34
 
@@ -79,23 +79,33 @@ function initializeGmap() {
79
 
80
  map = new google.maps.Map( document.getElementById( "wpsl-gmap" ), myOptions );
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  /* Check if we need to try and autolocate the user */
83
  if ( wpslSettings.autoLocate == 1 ) {
84
  checkGeolocation();
85
  } else {
86
- showStores();
 
 
87
  }
88
 
89
  /* Move the mousecursor to the store search field if the focus option is enabled */
90
  if ( wpslSettings.mouseFocus == 1 ) {
91
  $( "#wpsl-search-input" ).focus();
92
  }
93
-
94
- /* Style the dropdown menu */
95
- $selects.easyDropDown({
96
- cutOff: 10,
97
- wrapperClass: "wpsl-dropdown"
98
- });
99
  }
100
 
101
  function showStores() {
@@ -107,6 +117,16 @@ function showStores() {
107
  findStoreLocations( startLatLng, resetMap, autoLoad );
108
  }
109
 
 
 
 
 
 
 
 
 
 
 
110
  /* Check if Geolocation detection is supported. If there is an error / timeout with determining the users
111
  * location we use the 'start point' value from the settings as the start location through the showStores function.
112
  */
@@ -173,7 +193,7 @@ $( "#wpsl-search-btn" ).on( "click", function() {
173
  $( "#wpsl-reset-map" ).on( "click", function() {
174
  var keepStartMarker = false,
175
  resetMap = true;
176
-
177
  /* When the start marker is dragged the autoload value is set to false.
178
  * So we need to check the correct value when the reset button is pushed before reloading the stores.
179
  */
@@ -186,6 +206,11 @@ $( "#wpsl-reset-map" ).on( "click", function() {
186
  deleteOverlays( keepStartMarker );
187
  $( "#wpsl-search-input" ).val('').removeClass();
188
 
 
 
 
 
 
189
  /* Remove the start marker */
190
  deleteStartMarker();
191
 
@@ -222,8 +247,8 @@ function resetDropdowns() {
222
  $( "#" + dropdowns[i] + " li" ).removeClass();
223
 
224
  $( "#" + dropdowns[i] + " li" ).each( function () {
225
- if ( $(this).text() === defaultValues[i] ) {
226
- $(this).addClass('active');
227
  }
228
  });
229
  }
@@ -246,9 +271,14 @@ $( "#wpsl-result-list" ).on( "click", ".wpsl-back", function() {
246
  startMarkerData.setMap( map );
247
  }
248
 
249
- fitBounds();
250
- infoWindowDirectionButton();
251
-
 
 
 
 
 
252
  $( ".wpsl-direction-before, .wpsl-direction-after" ).remove();
253
  $( "#wpsl-stores" ).show();
254
  $( "#wpsl-direction-details" ).hide();
@@ -261,18 +291,24 @@ function renderDirections( e ) {
261
 
262
  /*
263
  The storeId is placed on the li in the results list,
264
- but in the marker it will be on the wrapper div. So we check which one we need to target
265
  */
266
  if ( e.parent( "li" ).length > 0 ) {
267
  storeId = e.parent( "li" ).data( "store-id" );
268
  } else {
269
- storeId = e.parent( ".wpsl-info-window" ).data( "store-id" );
270
  }
271
 
272
- /* Check if we need get the start point from a dragged marker */
273
  if ( ( typeof( startMarkerData ) !== "undefined" ) && ( startMarkerData !== "" ) ) {
274
  start = startMarkerData.getPosition();
275
  }
 
 
 
 
 
 
276
 
277
  /* Find the latlng that belongs to the start and end point */
278
  for ( i = 0, len = markersArray.length; i < len; i++ ) {
@@ -297,11 +333,11 @@ function renderDirections( e ) {
297
  /* Check if we need to enable the bouncing of markers when the user hovers over the result list */
298
  if ( wpslSettings.markerBounce == 1 ) {
299
  $( "#wpsl-stores" ).on( "mouseenter", "li", function() {
300
- letsBounce( $(this).data( "store-id" ), "start" );
301
  });
302
 
303
  $( "#wpsl-stores" ).on( "mouseleave", "li", function() {
304
- letsBounce( $(this).data( "store-id" ), "stop" );
305
  });
306
  }
307
 
@@ -364,11 +400,16 @@ function calcRoute( start, end ) {
364
 
365
  $( "#wpsl-direction-details ul" ).append( directionStops ).before( "<p class='wpsl-direction-before'><a class='wpsl-back' id='wpsl-direction-start' href='#'>" + wpslLabels.back + "</a>" + direction.legs[0].distance.text + " - " + direction.legs[0].duration.text + "</p>" ).after( "<p class='wpsl-direction-after'>" + response.routes[0].copyrights + "</p>" );
366
  $( "#wpsl-direction-details" ).show();
367
-
368
- /* Remove all other markers from the map */
369
  for ( i = 0, len = markersArray.length; i < len; i++ ) {
370
  markersArray[i].setMap( null );
371
  }
 
 
 
 
 
372
 
373
  /* Remove the start marker from the map */
374
  if ( ( typeof( startMarkerData ) !== "undefined" ) && ( startMarkerData !== "" ) ) {
@@ -378,11 +419,13 @@ function calcRoute( start, end ) {
378
  $( "#wpsl-stores" ).hide();
379
 
380
  /* Make sure the start of the route directions are visible if the store listings are shown below the map */
381
- if ( wpslSettings.storeBelow == 1 ) {
382
  directionOffset = $( "#wpsl-gmap" ).offset();
383
  $( window ).scrollTop( directionOffset.top );
384
  }
385
  }
 
 
386
  }
387
  });
388
  }
@@ -405,7 +448,7 @@ function codeAddress() {
405
  /* Try to find stores that match the radius, location criteria */
406
  findStoreLocations( latLng, resetMap, autoLoad );
407
  } else {
408
- geocodeNotification( status );
409
  }
410
  }
411
  )};
@@ -422,7 +465,7 @@ function reverseGeocode( latLng ) {
422
  $( "#wpsl-search-input" ).val( zipCode );
423
  }
424
  } else {
425
- geocodeNotification( status );
426
  }
427
  });
428
  }
@@ -464,13 +507,13 @@ function findFormattedAddress( latLng, callback ) {
464
  startAddress = response[0].formatted_address;
465
  callback();
466
  } else {
467
- geocodeNotification( status );
468
  }
469
  });
470
  }
471
 
472
  function makeAjaxRequest( startLatLng, resetMap, autoLoad ) {
473
- var location,
474
  infoWindowData = {},
475
  storeData = "",
476
  draggable = false,
@@ -486,16 +529,18 @@ function makeAjaxRequest( startLatLng, resetMap, autoLoad ) {
486
  target : ""
487
  };
488
 
489
- /*
490
- * If we reset the map we use the default dropdown
491
- * values instead of the selected values
492
- */
493
  if ( resetMap ) {
494
  ajaxData.max_results = wpslSettings.maxResults;
495
- ajaxData.radius = wpslSettings.searchRadius;
496
  } else {
497
- ajaxData.max_results = parseInt( $( "#wpsl-results .wpsl-dropdown .selected" ).text() );
498
- ajaxData.radius = parseInt( $( "#wpsl-radius .wpsl-dropdown .selected" ).text() );
 
 
 
 
 
499
  }
500
 
501
  /* Check if autoload all stores is enabled */
@@ -517,7 +562,8 @@ function makeAjaxRequest( startLatLng, resetMap, autoLoad ) {
517
  $.each( response, function( index ) {
518
  infoWindowData = {
519
  store: response[index].store,
520
- street: response[index].street,
 
521
  city: response[index].city,
522
  country: response[index].country,
523
  state: response[index].state,
@@ -531,10 +577,10 @@ function makeAjaxRequest( startLatLng, resetMap, autoLoad ) {
531
  thumb: response[index].thumb
532
  };
533
 
534
- location = new google.maps.LatLng( response[index].lat, response[index].lng );
535
- addMarker( location, response[index].id, infoWindowData, draggable );
536
  storeData = storeData + storeHtml( response[index], url );
537
- $("#wpsl-reset-map").show();
538
  });
539
 
540
  $( "#wpsl-result-list" ).off( "click", ".wpsl-directions" );
@@ -543,11 +589,15 @@ function makeAjaxRequest( startLatLng, resetMap, autoLoad ) {
543
  $( "#wpsl-result-list" ).on( "click", ".wpsl-directions", function() {
544
  /* Check if we need to disable the rendering of the direction on the map or not. */
545
  if ( wpslSettings.directionRedirect != 1 ) {
546
- renderDirections( $(this) );
547
  return false;
548
  }
549
  });
550
 
 
 
 
 
551
  fitBounds();
552
  } else {
553
  $storeList.html( "<li class='no-results'>" + wpslLabels.noResults + "</li>" );
@@ -560,13 +610,12 @@ function makeAjaxRequest( startLatLng, resetMap, autoLoad ) {
560
  /* If a reset button exists, store the default zoom and latlng values.
561
  * This way when a user clicks the reset button we can check if the zoom/latlng values have changed,
562
  * and if we actually have to reload the map.
563
- *
564
  */
565
- if ( $("#wpsl-reset-map").length > 0 ) {
566
  if ( $.isEmptyObject( mapDefaults ) ) {
567
  mapDefaults = {
568
- centerLatlng : map.getCenter(),
569
- zoomLevel : map.getZoom()
570
  };
571
  }
572
  }
@@ -574,13 +623,42 @@ function makeAjaxRequest( startLatLng, resetMap, autoLoad ) {
574
 
575
  /* Move the mousecursor to the store search field if the focus option is enabled */
576
  if ( wpslSettings.mouseFocus == 1 ) {
577
- $("#wpsl-search-input").focus();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
578
  }
579
  }
580
 
581
  /* Add a new marker to the map based on the provided location (latlng) */
582
- function addMarker( location, storeId, infoWindowData, draggable ) {
583
- var markerPath, mapIcon, keepStartMarker = true;
 
584
 
585
  if ( storeId === 0 ) {
586
  markerPath = wpslSettings.path + "img/markers/" + wpslSettings.startMarker;
@@ -588,39 +666,48 @@ function addMarker( location, storeId, infoWindowData, draggable ) {
588
  markerPath = wpslSettings.path + "img/markers/" + wpslSettings.storeMarker;
589
  }
590
 
591
- var mapIcon = {
592
  url: markerPath,
593
- size: new google.maps.Size( 48,70 ), //original format
594
  scaledSize: new google.maps.Size( 24,35 ), //retina format
595
  origin: new google.maps.Point( 0,0 ),
596
  anchor: new google.maps.Point( 12,35 )
597
  };
598
 
599
- var infoWindowContent,
600
- marker = new google.maps.Marker({
601
- position: location,
602
- map: map,
603
- optimized: false, //fixes markers flashing while bouncing
604
- title: infoWindowData.store,
605
- draggable: draggable,
606
- storeId: storeId,
607
- icon: mapIcon
608
- });
 
 
609
 
610
  google.maps.event.addListener( marker, "click", function() {
 
 
611
  if ( storeId != 0 ) {
612
- infoWindowContent = createInfoWindowHtml( infoWindowData, storeId );
613
- infowindow.setContent( infoWindowContent );
 
 
 
 
 
 
 
614
  } else {
615
- infowindow.setContent( wpslLabels.startPoint );
616
  }
617
-
618
- infowindow.open( map, marker );
619
- infoWindowDirectionButton();
 
 
620
  });
621
-
622
- /* Store the marker for later use */
623
- markersArray.push( marker );
624
 
625
  if ( draggable ) {
626
  google.maps.event.addListener( marker, "dragend", function( event ) {
@@ -632,22 +719,118 @@ function addMarker( location, storeId, infoWindowData, draggable ) {
632
  }
633
  }
634
 
635
- /* Activate the click listener for the direction buttons */
636
- function infoWindowDirectionButton() {
637
- $( ".wpsl-info-window" ).on( "click", ".wpsl-directions", function() {
638
- /* Check if we need to disable the rendering of the direction on the map or not. */
639
- if ( wpslSettings.directionRedirect != 1 ) {
640
- renderDirections( $(this) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641
  return false;
642
  }
643
  });
644
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
 
646
  /* Create the data for the infowindows on Google Maps */
647
- function createInfoWindowHtml( infoWindowData, storeId ) {
648
- var storeHeader,
649
- url,
650
  newWindow = "",
 
 
651
  windowContent = "<div data-store-id='" + storeId + "' class='wpsl-info-window'>";
652
 
653
  /* Check if we need to turn the store name into a link or not */
@@ -661,15 +844,19 @@ function createInfoWindowHtml( infoWindowData, storeId ) {
661
  storeHeader = "<strong>" + infoWindowData.store + "</strong>";
662
  }
663
 
664
- windowContent += "<p>" + storeHeader + "<span>" + infoWindowData.street + "</span><span>" + infoWindowData.city + "</span></p>";
 
 
 
 
665
 
666
  if ( ( typeof( infoWindowData.description ) !== "undefined" ) && ( infoWindowData.description !== "" ) ) {
667
  windowContent += "<p>" + infoWindowData.description + "</p>";
668
  }
669
 
670
- /* If no data exist for either the phone / fax / email then just don't show them */
671
  if ( ( typeof( infoWindowData.phone ) !== "undefined" ) && ( infoWindowData.phone !== "" ) ) {
672
- windowContent += "<span><strong>" + wpslLabels.phone + "</strong>: " + infoWindowData.phone + "</span>";
673
  }
674
 
675
  if ( ( typeof( infoWindowData.fax ) !== "undefined" ) && ( infoWindowData.fax !== "" ) ) {
@@ -685,20 +872,59 @@ function createInfoWindowHtml( infoWindowData, storeId ) {
685
  }
686
 
687
  if ( wpslSettings.directionRedirect == 1 ) {
688
- url = createDirectionUrl( infoWindowData.street, infoWindowData.city, infoWindowData.zip, infoWindowData.country );
689
  } else {
690
  url = {
691
  src : "#",
692
  target : ""
693
  };
694
  }
 
 
 
 
695
 
696
- windowContent += "<a class='wpsl-directions' " + url.target + " href='" + url.src + "'>" + wpslLabels.directions + "</a>";
697
- windowContent += "</div>";
 
 
 
 
698
 
699
  return windowContent;
700
  }
701
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
702
  function createMoreInfoListing( storeData ) {
703
  var newWindow = "",
704
  moreInfoContent = "<div id='wpsl-id-" + storeData.id + "' class='wpsl-more-info-listings'>";
@@ -711,7 +937,7 @@ function createMoreInfoListing( storeData ) {
711
 
712
  /* If no data exist for either the phone / fax / email then just don't show them */
713
  if ( ( typeof( storeData.phone ) !== "undefined" ) && ( storeData.phone !== "" ) ) {
714
- moreInfoContent += "<span><strong>" + wpslLabels.phone + "</strong>: " + storeData.phone + "</span>";
715
  }
716
 
717
  if ( ( typeof( storeData.fax ) !== "undefined" ) && ( storeData.fax !== "" ) ) {
@@ -741,7 +967,18 @@ function createMoreInfoListing( storeData ) {
741
  return moreInfoContent;
742
  }
743
 
744
- function createDirectionUrl( street, city, zip, country ) {
 
 
 
 
 
 
 
 
 
 
 
745
  var destinationAddress, url;
746
 
747
  /* If we somehow failed to determine the start address, just set it to empty */
@@ -749,39 +986,54 @@ function createDirectionUrl( street, city, zip, country ) {
749
  startAddress = '';
750
  }
751
 
752
- destinationAddress = street + ', ' + city + ', ' + zip + ', ' + country;
753
 
754
  url = {
755
- src : "https://maps.google.com/maps?saddr=" + encodeURIComponent( startAddress ) + "&daddr=" + encodeURIComponent( destinationAddress ) + "",
756
  target : "target='_blank'"
757
  };
758
 
759
  return url;
760
  }
761
 
 
 
 
 
 
 
 
 
 
 
 
 
 
762
  function storeHtml( response, url ) {
763
  var html = "",
764
  moreInfoData,
765
  storeImg = "",
 
766
  moreInfo = "",
767
  moreInfoUrl = "#",
768
  id = response.id,
769
  store = response.store,
770
- street = response.street,
 
771
  city = response.city,
772
  state = response.state,
773
  zip = response.zip,
774
  thumb = response.thumb,
775
  country = response.country,
776
  distance = parseFloat( response.distance ).toFixed(1) + " " + wpslSettings.distanceUnit;
777
-
778
  if ( ( typeof( thumb ) !== "undefined" ) && ( thumb !== "" ) ) {
779
  storeImg = "<img class='wpsl-store-thumb' src='" + thumb + "' width='48' height='48' alt='" + store + "' />";
780
  }
781
 
782
  /* Check if we need to create an url that sends the user to maps.google.com for driving directions */
783
  if ( wpslSettings.directionRedirect == 1 ) {
784
- url = createDirectionUrl( street, city, zip, country );
785
  }
786
 
787
  /* Check if we need to show the 'more info' link in the store listings */
@@ -790,10 +1042,13 @@ function storeHtml( response, url ) {
790
  /* If we show the store listings under the map, we do want to jump to the
791
  * top of the map to focus on the opened infowindow
792
  */
793
- if ( ( wpslSettings.storeBelow == 1 ) && ( wpslSettings.moreInfoLocation == 'info window' ) ) {
794
  moreInfoUrl = '#wpsl-search-wrap';
795
  }
796
 
 
 
 
797
  if ( wpslSettings.moreInfoLocation == "store listings" ) {
798
 
799
  /* Only create the 'more info' link if there is data to show */
@@ -809,8 +1064,26 @@ function storeHtml( response, url ) {
809
  moreInfo = "<p><a class='wpsl-store-details' href=" + moreInfoUrl + ">" + wpslLabels.moreInfo + "</a></p>";
810
  }
811
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
812
 
813
- html = "<li data-store-id='" + id + "'><div><p>" + storeImg + "<strong>" + store + "</strong><span class='wpsl-street'>" + street + "</span>" + city + " " + state + " " + zip + "<span class='wpsl-country'>" + country + "</p>" + moreInfo + "</div>" + distance + "<a class='wpsl-directions' " + url.target + " href='" + url.src + "'>" + wpslLabels.directions + "</a></li>";
814
 
815
  return html;
816
  }
@@ -857,10 +1130,21 @@ function deleteOverlays( keepStartMarker ) {
857
 
858
  markersArray.length = 0;
859
  }
 
 
 
 
 
860
  }
861
 
862
- /* Handle the geocode errors */
863
- function geocodeNotification( status ) {
 
 
 
 
 
 
864
  var msg;
865
 
866
  switch ( status ) {
@@ -878,6 +1162,32 @@ function geocodeNotification( status ) {
878
  alert( msg );
879
  }
880
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
881
  /* Trigger the search when the user presses "enter" on the keyboard */
882
  $( "#wpsl-search-input" ).keydown( function ( event ) {
883
  var keypressed = event.keyCode || event.which;
@@ -917,7 +1227,7 @@ $( "#wpsl-stores" ).on( "click", ".wpsl-store-details", function() {
917
  /* If we show the store listings under the map, we do want to jump to the
918
  * top of the map to focus on the opened infowindow
919
  */
920
- if ( wpslSettings.storeBelow != 1 || wpslSettings.moreInfoLocation == "store listings" ) {
921
  return false;
922
  }
923
  });
1
  jQuery( document ).ready( function( $ ) {
2
+ var geocoder, map, infoWindow, directionsDisplay, directionsService, geolocationLatlng, markerClusterer,
3
  markersArray = [],
4
+ directionMarkerPosition = {},
5
  mapDefaults = {},
6
  resetMap = false,
7
+ streetViewAvailable = false,
8
  startMarkerData,
9
  startAddress,
10
  startLatLng,
11
  autoLoad = wpslSettings.autoLoad,
12
  $selects = $( "#wpsl-search-wrap select" );
13
 
14
+ /* Initialize the map with the correct settings */
15
  function initializeGmap() {
16
  var myOptions, zoomControlPosition, zoomControlStyle,
17
  latLng, zoomLevel, mapType,
19
 
20
  /* If no zoom location is defined, we show the entire world */
21
  if ( wpslSettings.zoomLatlng !== '' ) {
22
+ latLng = wpslSettings.zoomLatlng.split( ',' );
23
  startLatLng = new google.maps.LatLng( latLng[0], latLng[1] );
24
+ zoomLevel = parseInt( wpslSettings.zoomLevel );
25
  } else {
26
  startLatLng = new google.maps.LatLng( 0,0 );
27
+ zoomLevel = 1;
28
  }
29
 
30
+ geocoder = new google.maps.Geocoder();
31
+ infoWindow = new google.maps.InfoWindow();
 
 
32
  directionsDisplay = new google.maps.DirectionsRenderer();
33
  directionsService = new google.maps.DirectionsService();
34
 
79
 
80
  map = new google.maps.Map( document.getElementById( "wpsl-gmap" ), myOptions );
81
 
82
+ /* Not the most optimal solution, but we check the useragent if we should enable the easydropdown library.
83
+ * We do this because several people have reported issues with it on iOS and Android devices. So on mobile
84
+ * devices the dropdowns will be styled according to the browser styles on that device.
85
+ */
86
+ if ( !checkMobileUserAgent() ) {
87
+ $selects.easyDropDown({
88
+ cutOff: 10,
89
+ wrapperClass: "wpsl-dropdown"
90
+ });
91
+ } else {
92
+ $( "#wpsl-search-wrap select").show();
93
+ $( "#wpsl-wrap" ).addClass( 'wpsl-mobile' );
94
+ }
95
+
96
  /* Check if we need to try and autolocate the user */
97
  if ( wpslSettings.autoLocate == 1 ) {
98
  checkGeolocation();
99
  } else {
100
+ if ( wpslSettings.autoLoad == 1 ) {
101
+ showStores();
102
+ }
103
  }
104
 
105
  /* Move the mousecursor to the store search field if the focus option is enabled */
106
  if ( wpslSettings.mouseFocus == 1 ) {
107
  $( "#wpsl-search-input" ).focus();
108
  }
 
 
 
 
 
 
109
  }
110
 
111
  function showStores() {
117
  findStoreLocations( startLatLng, resetMap, autoLoad );
118
  }
119
 
120
+ /**
121
+ * Compare the current useragent to a list of known mobile useragents ( not optimal, I know )
122
+ *
123
+ * @since 1.2.20
124
+ * @returns {boolean} Whether the useragent is from a known mobile useragent or not.
125
+ */
126
+ function checkMobileUserAgent() {
127
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent );
128
+ }
129
+
130
  /* Check if Geolocation detection is supported. If there is an error / timeout with determining the users
131
  * location we use the 'start point' value from the settings as the start location through the showStores function.
132
  */
193
  $( "#wpsl-reset-map" ).on( "click", function() {
194
  var keepStartMarker = false,
195
  resetMap = true;
196
+
197
  /* When the start marker is dragged the autoload value is set to false.
198
  * So we need to check the correct value when the reset button is pushed before reloading the stores.
199
  */
206
  deleteOverlays( keepStartMarker );
207
  $( "#wpsl-search-input" ).val('').removeClass();
208
 
209
+ /* If marker clusters exist, remove them from the map */
210
+ if ( markerClusterer ) {
211
+ markerClusterer.clearMarkers();
212
+ }
213
+
214
  /* Remove the start marker */
215
  deleteStartMarker();
216
 
247
  $( "#" + dropdowns[i] + " li" ).removeClass();
248
 
249
  $( "#" + dropdowns[i] + " li" ).each( function () {
250
+ if ( $( this ).text() === defaultValues[i] ) {
251
+ $( this ).addClass('active');
252
  }
253
  });
254
  }
271
  startMarkerData.setMap( map );
272
  }
273
 
274
+ /* If marker clusters are enabled, then restore them */
275
+ if ( markerClusterer ) {
276
+ checkMarkerClusters();
277
+ }
278
+
279
+ map.setCenter( directionMarkerPosition.centerLatlng );
280
+ map.setZoom( directionMarkerPosition.zoomLevel );
281
+
282
  $( ".wpsl-direction-before, .wpsl-direction-after" ).remove();
283
  $( "#wpsl-stores" ).show();
284
  $( "#wpsl-direction-details" ).hide();
291
 
292
  /*
293
  The storeId is placed on the li in the results list,
294
+ but in the marker it will be on the wrapper div. So we check which one we need to target.
295
  */
296
  if ( e.parent( "li" ).length > 0 ) {
297
  storeId = e.parent( "li" ).data( "store-id" );
298
  } else {
299
+ storeId = e.parents( ".wpsl-info-window" ).data( "store-id" );
300
  }
301
 
302
+ /* Check if we need to get the start point from a dragged marker */
303
  if ( ( typeof( startMarkerData ) !== "undefined" ) && ( startMarkerData !== "" ) ) {
304
  start = startMarkerData.getPosition();
305
  }
306
+
307
+ /* Used to restore the map back to the state it was in before the user clicked on 'directions' */
308
+ directionMarkerPosition = {
309
+ centerLatlng: map.getCenter(),
310
+ zoomLevel: map.getZoom()
311
+ };
312
 
313
  /* Find the latlng that belongs to the start and end point */
314
  for ( i = 0, len = markersArray.length; i < len; i++ ) {
333
  /* Check if we need to enable the bouncing of markers when the user hovers over the result list */
334
  if ( wpslSettings.markerBounce == 1 ) {
335
  $( "#wpsl-stores" ).on( "mouseenter", "li", function() {
336
+ letsBounce( $( this ).data( "store-id" ), "start" );
337
  });
338
 
339
  $( "#wpsl-stores" ).on( "mouseleave", "li", function() {
340
+ letsBounce( $( this ).data( "store-id" ), "stop" );
341
  });
342
  }
343
 
400
 
401
  $( "#wpsl-direction-details ul" ).append( directionStops ).before( "<p class='wpsl-direction-before'><a class='wpsl-back' id='wpsl-direction-start' href='#'>" + wpslLabels.back + "</a>" + direction.legs[0].distance.text + " - " + direction.legs[0].duration.text + "</p>" ).after( "<p class='wpsl-direction-after'>" + response.routes[0].copyrights + "</p>" );
402
  $( "#wpsl-direction-details" ).show();
403
+
404
+ /* Remove all single markers from the map */
405
  for ( i = 0, len = markersArray.length; i < len; i++ ) {
406
  markersArray[i].setMap( null );
407
  }
408
+
409
+ /* Remove the marker clusters from the map */
410
+ if ( markerClusterer ) {
411
+ markerClusterer.clearMarkers();
412
+ }
413
 
414
  /* Remove the start marker from the map */
415
  if ( ( typeof( startMarkerData ) !== "undefined" ) && ( startMarkerData !== "" ) ) {
419
  $( "#wpsl-stores" ).hide();
420
 
421
  /* Make sure the start of the route directions are visible if the store listings are shown below the map */
422
+ if ( wpslSettings.templateId == 1 ) {
423
  directionOffset = $( "#wpsl-gmap" ).offset();
424
  $( window ).scrollTop( directionOffset.top );
425
  }
426
  }
427
+ } else {
428
+ directionErrors( status );
429
  }
430
  });
431
  }
448
  /* Try to find stores that match the radius, location criteria */
449
  findStoreLocations( latLng, resetMap, autoLoad );
450
  } else {
451
+ geocodeErrors( status );
452
  }
453
  }
454
  )};
465
  $( "#wpsl-search-input" ).val( zipCode );
466
  }
467
  } else {
468
+ geocodeErrors( status );
469
  }
470
  });
471
  }
507
  startAddress = response[0].formatted_address;
508
  callback();
509
  } else {
510
+ hanleErrors( status );
511
  }
512
  });
513
  }
514
 
515
  function makeAjaxRequest( startLatLng, resetMap, autoLoad ) {
516
+ var latLng,
517
  infoWindowData = {},
518
  storeData = "",
519
  draggable = false,
529
  target : ""
530
  };
531
 
532
+ /* If we reset the map we use the default dropdown values instead of the selected values. */
 
 
 
533
  if ( resetMap ) {
534
  ajaxData.max_results = wpslSettings.maxResults;
535
+ ajaxData.radius = wpslSettings.searchRadius;
536
  } else {
537
+ if ( $( "#wpsl-wrap" ).hasClass( "wpsl-mobile" ) ) {
538
+ ajaxData.max_results = $( "#wpsl-results .wpsl-dropdown" ).val();
539
+ ajaxData.radius = $( "#wpsl-radius .wpsl-dropdown" ).val();
540
+ } else {
541
+ ajaxData.max_results = parseInt( $( "#wpsl-results .wpsl-dropdown .selected" ).text() );
542
+ ajaxData.radius = parseInt( $( "#wpsl-radius .wpsl-dropdown .selected" ).text() );
543
+ }
544
  }
545
 
546
  /* Check if autoload all stores is enabled */
562
  $.each( response, function( index ) {
563
  infoWindowData = {
564
  store: response[index].store,
565
+ address: response[index].address,
566
+ address2: response[index].address2,
567
  city: response[index].city,
568
  country: response[index].country,
569
  state: response[index].state,
577
  thumb: response[index].thumb
578
  };
579
 
580
+ latLng = new google.maps.LatLng( response[index].lat, response[index].lng );
581
+ addMarker( latLng, response[index].id, infoWindowData, draggable );
582
  storeData = storeData + storeHtml( response[index], url );
583
+ $( "#wpsl-reset-map" ).show();
584
  });
585
 
586
  $( "#wpsl-result-list" ).off( "click", ".wpsl-directions" );
589
  $( "#wpsl-result-list" ).on( "click", ".wpsl-directions", function() {
590
  /* Check if we need to disable the rendering of the direction on the map or not. */
591
  if ( wpslSettings.directionRedirect != 1 ) {
592
+ renderDirections( $( this ) );
593
  return false;
594
  }
595
  });
596
 
597
+ /* Do we need to create a marker cluster? */
598
+ checkMarkerClusters();
599
+
600
+ /* Make sure everything fits on the screen */
601
  fitBounds();
602
  } else {
603
  $storeList.html( "<li class='no-results'>" + wpslLabels.noResults + "</li>" );
610
  /* If a reset button exists, store the default zoom and latlng values.
611
  * This way when a user clicks the reset button we can check if the zoom/latlng values have changed,
612
  * and if we actually have to reload the map.
 
613
  */
614
+ if ( $( "#wpsl-reset-map" ).length > 0 ) {
615
  if ( $.isEmptyObject( mapDefaults ) ) {
616
  mapDefaults = {
617
+ centerLatlng: map.getCenter(),
618
+ zoomLevel: map.getZoom()
619
  };
620
  }
621
  }
623
 
624
  /* Move the mousecursor to the store search field if the focus option is enabled */
625
  if ( wpslSettings.mouseFocus == 1 ) {
626
+ $( "#wpsl-search-input" ).focus();
627
+ }
628
+ }
629
+
630
+ /**
631
+ * Check if cluster markers are enabled.
632
+ * If so, init the marker clustering with the
633
+ * correct gridsize and max zoom.
634
+ *
635
+ * @since 1.2.20
636
+ * @return {void}
637
+ */
638
+ function checkMarkerClusters() {
639
+ if ( wpslSettings.markerClusters == 1 ) {
640
+ var clusterZoom = Number( wpslSettings.clusterZoom ),
641
+ clusterSize = Number( wpslSettings.clusterSize );
642
+
643
+ if ( isNaN( clusterZoom ) ) {
644
+ clusterZoom = "";
645
+ }
646
+
647
+ if ( isNaN( clusterSize ) ) {
648
+ clusterSize = "";
649
+ }
650
+
651
+ markerClusterer = new MarkerClusterer( map, markersArray, {
652
+ gridSize: clusterSize,
653
+ maxZoom: clusterZoom
654
+ });
655
  }
656
  }
657
 
658
  /* Add a new marker to the map based on the provided location (latlng) */
659
+ function addMarker( latLng, storeId, infoWindowData, draggable ) {
660
+ var markerPath, mapIcon, marker,
661
+ keepStartMarker = true;
662
 
663
  if ( storeId === 0 ) {
664
  markerPath = wpslSettings.path + "img/markers/" + wpslSettings.startMarker;
666
  markerPath = wpslSettings.path + "img/markers/" + wpslSettings.storeMarker;
667
  }
668
 
669
+ mapIcon = {
670
  url: markerPath,
 
671
  scaledSize: new google.maps.Size( 24,35 ), //retina format
672
  origin: new google.maps.Point( 0,0 ),
673
  anchor: new google.maps.Point( 12,35 )
674
  };
675
 
676
+ marker = new google.maps.Marker({
677
+ position: latLng,
678
+ map: map,
679
+ optimized: false, //fixes markers flashing while bouncing
680
+ title: infoWindowData.store,
681
+ draggable: draggable,
682
+ storeId: storeId,
683
+ icon: mapIcon
684
+ });
685
+
686
+ /* Store the marker for later use */
687
+ markersArray.push( marker );
688
 
689
  google.maps.event.addListener( marker, "click", function() {
690
+
691
+ /* The start marker will have a store id of 0, all others won't */
692
  if ( storeId != 0 ) {
693
+
694
+ /* Check if streetview is available at the clicked location */
695
+ if ( wpslSettings.markerStreetView == 1) {
696
+ checkStreetViewStatus( latLng, function() {
697
+ setInfoWindowContent( marker, createInfoWindowHtml( infoWindowData, storeId, streetViewAvailable ) );
698
+ });
699
+ } else {
700
+ setInfoWindowContent( marker, createInfoWindowHtml( infoWindowData, storeId, streetViewAvailable ) );
701
+ }
702
  } else {
703
+ setInfoWindowContent( marker, wpslLabels.startPoint );
704
  }
705
+
706
+ google.maps.event.clearListeners( infoWindow );
707
+ google.maps.event.addListener( infoWindow, "domready", function() {
708
+ infoWindowActions( marker, latLng );
709
+ });
710
  });
 
 
 
711
 
712
  if ( draggable ) {
713
  google.maps.event.addListener( marker, "dragend", function( event ) {
719
  }
720
  }
721
 
722
+ /**
723
+ * Set the correct infowindow content for the marker
724
+ *
725
+ * @since 1.2.20
726
+ * @param {object} marker Marker data
727
+ * @param {string} InfoWindowContent The infowindow content
728
+ * @returns {void}
729
+ */
730
+ function setInfoWindowContent( marker, InfoWindowContent ) {
731
+ infoWindow.setContent( InfoWindowContent );
732
+ infoWindow.open( map, marker );
733
+ }
734
+
735
+ /**
736
+ * Handle clicks for the different infowindow actions like,
737
+ * direction, streetview and zoom here.
738
+ *
739
+ * @since 1.2.20
740
+ * @param {object} marker Holds the marker data
741
+ * @param {object} activelatLng The latng of the clicked marker
742
+ * @returns {void}
743
+ */
744
+ function infoWindowActions( marker, activelatLng ) {
745
+ $( ".wpsl-info-actions a" ).on( "click", function() {
746
+ if ( $( this ).hasClass( "wpsl-directions" ) ) {
747
+
748
+ /* Check if we need to show the direction on the map
749
+ * or send the users to maps.google.com
750
+ */
751
+ if ( wpslSettings.directionRedirect != 1 ) {
752
+ renderDirections( $( this ) );
753
+
754
+ return false;
755
+ }
756
+ } else if ( $( this ).hasClass( "wpsl-streetview" ) ) {
757
+ activateStreetView( marker );
758
+
759
+ return false;
760
+ } else if ( $( this ).hasClass( "wpsl-zoom-here" ) ) {
761
+ map.setCenter( activelatLng );
762
+ map.setZoom( 15 );
763
+
764
  return false;
765
  }
766
  });
767
  }
768
+
769
+ /**
770
+ * Activate streetview for the clicked location
771
+ *
772
+ * @since 1.2.20
773
+ * @param {object} marker The current marker
774
+ * @returns {void}
775
+ */
776
+ function activateStreetView( marker ) {
777
+ var panorama = map.getStreetView();
778
+ panorama.setPosition( marker.getPosition() );
779
+ panorama.setVisible( true );
780
+
781
+ $( "#wpsl-reset-map" ).hide();
782
+
783
+ StreetViewListener( panorama );
784
+ }
785
+
786
+ /**
787
+ * Listen for changes in the streetview visibility
788
+ *
789
+ * Sometimes the infowindow offset is incorrect after switching back from streetview.
790
+ * We fix this by zooming in and out. If someone has a better fix, then let me know at
791
+ * info at tijmensmit.com
792
+ *
793
+ * @since 1.2.20
794
+ * @param {object} marker The current marker
795
+ * @returns {void}
796
+ */
797
+ function StreetViewListener( panorama ) {
798
+ google.maps.event.addListener( panorama, 'visible_changed', function() {
799
+ if ( !panorama.getVisible() ) {
800
+ var currentZoomLevel = map.getZoom();
801
+ $( "#wpsl-reset-map" ).show();
802
+
803
+ map.setZoom( currentZoomLevel-1 );
804
+ map.setZoom( currentZoomLevel );
805
+ }
806
+ });
807
+ }
808
+
809
+ /**
810
+ * Check the streetview status
811
+ *
812
+ * Make sure that a streetview exists for the latlng
813
+ *
814
+ * @since 1.2.20
815
+ * @param {object} latLng The latlng coordinates
816
+ * @returns {void}
817
+ */
818
+ function checkStreetViewStatus( latLng, callback ) {
819
+ var service = new google.maps.StreetViewService();
820
+
821
+ service.getPanoramaByLocation( latLng, 50, function( result, status ) {
822
+ streetViewAvailable = ( status == google.maps.StreetViewStatus.OK ) ? true : false;
823
+ callback();
824
+ });
825
+ }
826
 
827
  /* Create the data for the infowindows on Google Maps */
828
+ function createInfoWindowHtml( infoWindowData, storeId, streetViewAvailable ) {
829
+ var storeHeader, url,
830
+ address2 = "",
831
  newWindow = "",
832
+ streetView = "",
833
+ zoomTo = "",
834
  windowContent = "<div data-store-id='" + storeId + "' class='wpsl-info-window'>";
835
 
836
  /* Check if we need to turn the store name into a link or not */
844
  storeHeader = "<strong>" + infoWindowData.store + "</strong>";
845
  }
846
 
847
+ if ( ( typeof( infoWindowData.address2 ) !== "undefined" ) && ( infoWindowData.address2 !== "" ) ) {
848
+ address2 = "<span>" + infoWindowData.address2 + "</span>";
849
+ }
850
+
851
+ windowContent += "<p>" + storeHeader + "<span>" + infoWindowData.address + "</span>" + address2 + "<span>" + infoWindowData.city + "</span></p>";
852
 
853
  if ( ( typeof( infoWindowData.description ) !== "undefined" ) && ( infoWindowData.description !== "" ) ) {
854
  windowContent += "<p>" + infoWindowData.description + "</p>";
855
  }
856
 
857
+ /* If no data exist for either the phone / fax / email then we just don't show them */
858
  if ( ( typeof( infoWindowData.phone ) !== "undefined" ) && ( infoWindowData.phone !== "" ) ) {
859
+ windowContent += "<span><strong>" + wpslLabels.phone + "</strong>: " + formatPhoneNumber( infoWindowData.phone ) + "</span>";
860
  }
861
 
862
  if ( ( typeof( infoWindowData.fax ) !== "undefined" ) && ( infoWindowData.fax !== "" ) ) {
872
  }
873
 
874
  if ( wpslSettings.directionRedirect == 1 ) {
875
+ url = createDirectionUrl( infoWindowData.address, infoWindowData.city, infoWindowData.zip, infoWindowData.country );
876
  } else {
877
  url = {
878
  src : "#",
879
  target : ""
880
  };
881
  }
882
+
883
+ if ( streetViewAvailable ) {
884
+ streetView = "<a class='wpsl-streetview' href='#'>" + wpslLabels.streetView + "</a>";
885
+ }
886
 
887
+ if ( wpslSettings.markerZoomTo == 1 ) {
888
+ zoomTo = "<a class='wpsl-zoom-here' href='#'>" + wpslLabels.zoomHere + "</a>";
889
+ }
890
+
891
+ windowContent += "<div class='wpsl-info-actions'><a class='wpsl-directions' " + url.target + " href='" + url.src + "'>" + wpslLabels.directions + "</a>" + streetView + zoomTo + "</div>";
892
+ windowContent += "</div>";
893
 
894
  return windowContent;
895
  }
896
 
897
+ /**
898
+ * Make the phone number clickable if we are dealing with a mobile useragent
899
+ *
900
+ * @since 1.2.20
901
+ * @param {string} phoneNumber The phone number
902
+ * @returns {string} phoneNumber Either just the plain number, or with a link wrapped around it with tel:
903
+ */
904
+ function formatPhoneNumber( phoneNumber ) {
905
+ if ( ( wpslSettings.phoneUrl == 1 ) && ( checkMobileUserAgent() ) ) {
906
+ phoneNumber = "<a href='tel:" + formatClickablePhoneNumber( phoneNumber ) + "'>" + phoneNumber + "</a>";
907
+ }
908
+
909
+ return phoneNumber;
910
+ }
911
+
912
+ /**
913
+ * Replace spaces - . and () from phone numbers.
914
+ * Also if the number starts with a + we check for a (0) and remove it.
915
+ *
916
+ * @since 1.2.20
917
+ * @param {string} phoneNumber The phone number
918
+ * @returns {string} phoneNumber The 'cleaned' number
919
+ */
920
+ function formatClickablePhoneNumber( phoneNumber ) {
921
+ if ( ( phoneNumber.indexOf( "+" ) != -1 ) && ( phoneNumber.indexOf( "(0)" ) != -1 ) ) {
922
+ phoneNumber = phoneNumber.replace( '(0)', '' );
923
+ }
924
+
925
+ return phoneNumber.replace( /(-| |\(|\)|\.|)/g, '' );
926
+ }
927
+
928
  function createMoreInfoListing( storeData ) {
929
  var newWindow = "",
930
  moreInfoContent = "<div id='wpsl-id-" + storeData.id + "' class='wpsl-more-info-listings'>";
937
 
938
  /* If no data exist for either the phone / fax / email then just don't show them */
939
  if ( ( typeof( storeData.phone ) !== "undefined" ) && ( storeData.phone !== "" ) ) {
940
+ moreInfoContent += "<span><strong>" + wpslLabels.phone + "</strong>: " + formatPhoneNumber( storeData.phone ) + "</span>";
941
  }
942
 
943
  if ( ( typeof( storeData.fax ) !== "undefined" ) && ( storeData.fax !== "" ) ) {
967
  return moreInfoContent;
968
  }
969
 
970
+ /**
971
+ * Create the url that takes the user to the maps.google.com page
972
+ * and shows the correct driving directions.
973
+ *
974
+ * @since 1.0
975
+ * @param {string} address The store address
976
+ * @param {string} city The store city
977
+ * @param {string} zip The store zipcode
978
+ * @param {string} country The store country
979
+ * @returns {string} url The full maps.google.com url with the encoded start + end address
980
+ */
981
+ function createDirectionUrl( address, city, zip, country ) {
982
  var destinationAddress, url;
983
 
984
  /* If we somehow failed to determine the start address, just set it to empty */
986
  startAddress = '';
987
  }
988
 
989
+ destinationAddress = address + ', ' + city + ', ' + zip + ', ' + country;
990
 
991
  url = {
992
+ src : "https://maps.google.com/maps?saddr=" + rfc3986EncodeURIComponent( startAddress ) + "&daddr=" + rfc3986EncodeURIComponent( destinationAddress ) + "",
993
  target : "target='_blank'"
994
  };
995
 
996
  return url;
997
  }
998
 
999
+ /**
1000
+ * Make the URI encoding compatible with RFC 3986
1001
+ *
1002
+ * !, ', (, ), and * will be escaped, otherwise they break the string
1003
+ *
1004
+ * @since 1.2.20
1005
+ * @param {string} str The string to encode
1006
+ * @returns {string} The encoded string
1007
+ */
1008
+ function rfc3986EncodeURIComponent( str ) {
1009
+ return encodeURIComponent( str ).replace( /[!'()*]/g, escape );
1010
+ }
1011
+
1012
  function storeHtml( response, url ) {
1013
  var html = "",
1014
  moreInfoData,
1015
  storeImg = "",
1016
+ storeUrlTarget = "",
1017
  moreInfo = "",
1018
  moreInfoUrl = "#",
1019
  id = response.id,
1020
  store = response.store,
1021
+ address = response.address,
1022
+ address2 = "",
1023
  city = response.city,
1024
  state = response.state,
1025
  zip = response.zip,
1026
  thumb = response.thumb,
1027
  country = response.country,
1028
  distance = parseFloat( response.distance ).toFixed(1) + " " + wpslSettings.distanceUnit;
1029
+
1030
  if ( ( typeof( thumb ) !== "undefined" ) && ( thumb !== "" ) ) {
1031
  storeImg = "<img class='wpsl-store-thumb' src='" + thumb + "' width='48' height='48' alt='" + store + "' />";
1032
  }
1033
 
1034
  /* Check if we need to create an url that sends the user to maps.google.com for driving directions */
1035
  if ( wpslSettings.directionRedirect == 1 ) {
1036
+ url = createDirectionUrl( address, city, zip, country );
1037
  }
1038
 
1039
  /* Check if we need to show the 'more info' link in the store listings */
1042
  /* If we show the store listings under the map, we do want to jump to the
1043
  * top of the map to focus on the opened infowindow
1044
  */
1045
+ if ( ( wpslSettings.templateId == 1 ) && ( wpslSettings.moreInfoLocation == 'info window' ) ) {
1046
  moreInfoUrl = '#wpsl-search-wrap';
1047
  }
1048
 
1049
+ /* Do we need to show the 'more info' data under the store details,
1050
+ * or should we only add a link which will trigger the infowindow?
1051
+ */
1052
  if ( wpslSettings.moreInfoLocation == "store listings" ) {
1053
 
1054
  /* Only create the 'more info' link if there is data to show */
1064
  moreInfo = "<p><a class='wpsl-store-details' href=" + moreInfoUrl + ">" + wpslLabels.moreInfo + "</a></p>";
1065
  }
1066
  }
1067
+
1068
+ /* Check if we need to make the store name clickable */
1069
+ if ( wpslSettings.storeUrl == 1) {
1070
+ if ( ( typeof( response.url ) !== "undefined" ) && ( response.url !== "" ) ) {
1071
+
1072
+ /* Do we need to open the url in a new window? */
1073
+ if ( wpslSettings.newWindow == 1 ) {
1074
+ storeUrlTarget = "target='_blank'";
1075
+ }
1076
+
1077
+ store = "<a " + storeUrlTarget + " href=" + response.url + ">" + store + "</a>";
1078
+ }
1079
+ }
1080
+
1081
+ /* If we have a second address line, we add it */
1082
+ if ( ( typeof( response.address2 ) !== "undefined" ) && ( response.address2 !== "" ) ) {
1083
+ address2 = "<span class='wpsl-street'>" + response.address2 + "</span>";
1084
+ }
1085
 
1086
+ html = "<li data-store-id='" + id + "'><div><p>" + storeImg + "<strong>" + store + "</strong><span class='wpsl-street'>" + address + "</span>" + address2 + city + " " + state + " " + zip + "<span class='wpsl-country'>" + country + "</p>" + moreInfo + "</div>" + distance + "<a class='wpsl-directions' " + url.target + " href='" + url.src + "'>" + wpslLabels.directions + "</a></li>";
1087
 
1088
  return html;
1089
  }
1130
 
1131
  markersArray.length = 0;
1132
  }
1133
+
1134
+ /* If marker clusters exist, remove them from the map */
1135
+ if ( markerClusterer ) {
1136
+ markerClusterer.clearMarkers();
1137
+ }
1138
  }
1139
 
1140
+ /**
1141
+ * Handle the geocode errors.
1142
+ *
1143
+ * @since 1.0
1144
+ * @param {string} status Contains the error code
1145
+ * @returns void
1146
+ */
1147
+ function geocodeErrors( status ) {
1148
  var msg;
1149
 
1150
  switch ( status ) {
1162
  alert( msg );
1163
  }
1164
 
1165
+ /**
1166
+ * Handle the driving direction errors.
1167
+ *
1168
+ * @since 1.2.20
1169
+ * @param {string} status Contains the error code
1170
+ * @returns void
1171
+ */
1172
+ function directionErrors( status ) {
1173
+ var msg;
1174
+
1175
+ switch ( status ) {
1176
+ case "NOT_FOUND":
1177
+ case "ZERO_RESULTS":
1178
+ msg = wpslLabels.noDirectionsFound;
1179
+ break;
1180
+ case "OVER_QUERY_LIMIT":
1181
+ msg = wpslLabels.queryLimit;
1182
+ break;
1183
+ default:
1184
+ msg = wpslLabels.generalError;
1185
+ break;
1186
+ }
1187
+
1188
+ alert( msg );
1189
+ }
1190
+
1191
  /* Trigger the search when the user presses "enter" on the keyboard */
1192
  $( "#wpsl-search-input" ).keydown( function ( event ) {
1193
  var keypressed = event.keyCode || event.which;
1227
  /* If we show the store listings under the map, we do want to jump to the
1228
  * top of the map to focus on the opened infowindow
1229
  */
1230
+ if ( wpslSettings.templateId != 1 || wpslSettings.moreInfoLocation == "store listings" ) {
1231
  return false;
1232
  }
1233
  });
languages/wpsl-nl_NL.mo ADDED
Binary file
languages/wpsl-nl_NL.po ADDED
@@ -0,0 +1,1955 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: WP Store Locator v1.2.20\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2014-05-11 20:54+0100\n"
6
+ "PO-Revision-Date: 2014-05-13 12:03+0100\n"
7
+ "Last-Translator: \n"
8
+ "Language-Team: \n"
9
+ "Language: nl_NL\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
+ "X-Generator: Poedit 1.6.5\n"
15
+ "X-Poedit-SourceCharset: utf-8\n"
16
+ "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
17
+ "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
18
+ "X-Poedit-Basepath: ../\n"
19
+ "X-Textdomain-Support: yes\n"
20
+ "X-Poedit-SearchPath-0: .\n"
21
+
22
+ #: admin/class-admin.php:128 wp-store-locator.php:268
23
+ msgid "More info"
24
+ msgstr "Meer info"
25
+
26
+ #: admin/class-admin.php:144
27
+ msgid "info window"
28
+ msgstr "info window"
29
+
30
+ #: admin/class-admin.php:149 wp-store-locator.php:271
31
+ msgid "Back"
32
+ msgstr "Terug"
33
+
34
+ #: admin/class-admin.php:154 wp-store-locator.php:272
35
+ msgid "Reset"
36
+ msgstr "Herstel"
37
+
38
+ #: admin/class-admin.php:211 wp-store-locator.php:273
39
+ msgid "Street view"
40
+ msgstr "Street view"
41
+
42
+ #: admin/class-admin.php:215 wp-store-locator.php:274
43
+ msgid "Zoom here"
44
+ msgstr "Zoom hier"
45
+
46
+ #: admin/class-admin.php:219 wp-store-locator.php:270
47
+ msgid "No route could be found between the origin and destination"
48
+ msgstr "Er kon geen route gevonden worden tussen het begin en eindpunt"
49
+
50
+ #: admin/class-admin.php:247
51
+ msgid "Store Locator"
52
+ msgstr "Store Locator"
53
+
54
+ #: admin/class-admin.php:248
55
+ msgid "Manage Stores"
56
+ msgstr "Beheer Locaties"
57
+
58
+ #: admin/class-admin.php:249 admin/class-admin.php:574
59
+ #: admin/templates/add-store.php:107
60
+ msgid "Add Store"
61
+ msgstr "Locatie Toevoegen"
62
+
63
+ #: admin/class-admin.php:250 admin/class-admin.php:575
64
+ #: admin/templates/map-settings.php:2
65
+ msgid "Settings"
66
+ msgstr "Instellingen"
67
+
68
+ #: admin/class-admin.php:251 admin/templates/faq.php:2
69
+ msgid "FAQ"
70
+ msgstr "FAQ"
71
+
72
+ #: admin/class-admin.php:267 admin/class-store-overview.php:31
73
+ msgid "Stores"
74
+ msgstr "Locaties"
75
+
76
+ #: admin/class-admin.php:436
77
+ msgid "There was a problem updating the store details, please try again."
78
+ msgstr "De locatie data kon niet worden gewijzigd, probeer het nog een keer."
79
+
80
+ #: admin/class-admin.php:440
81
+ msgid "Store details updated."
82
+ msgstr "Locatie data bijgewerkt."
83
+
84
+ #: admin/class-admin.php:486
85
+ msgid "There was a problem saving the new store details, please try again."
86
+ msgstr "De locatie data kon niet worden opgeslagen, probeer het nog een keer."
87
+
88
+ #: admin/class-admin.php:490
89
+ msgid "Store succesfully added."
90
+ msgstr "Locatie succesvol toegevoegd."
91
+
92
+ #: admin/class-admin.php:521
93
+ msgid "Please fill in all the required fields."
94
+ msgstr "Vul alle verplichte velden in."
95
+
96
+ #: admin/class-admin.php:573
97
+ msgid "Current Stores"
98
+ msgstr "Huidige Locaties"
99
+
100
+ #: admin/class-admin.php:610
101
+ msgid ""
102
+ "The max results field cannot be empty, the default value has been restored."
103
+ msgstr ""
104
+ "Het max zoek resulaten veld kan niet leeg zijn, de standaard waarde is "
105
+ "hersteld."
106
+
107
+ #: admin/class-admin.php:613
108
+ msgid ""
109
+ "The search radius field cannot be empty, the default value has been restored."
110
+ msgstr ""
111
+ "Het zoek radius veld kan niet leeg zijn, de standaard waarde is hersteld."
112
+
113
+ #: admin/class-admin.php:616
114
+ msgid ""
115
+ "One of the label fields was left empty, the default value for that field has "
116
+ "been restored."
117
+ msgstr "Een van de label velden was leeg, de standaard waarde is hersteld."
118
+
119
+ #: admin/class-admin.php:619
120
+ msgid ""
121
+ "Please provide the name of a city or country that can be used as a starting "
122
+ "point under \"Map Settings\". This will only be used if auto-locating the "
123
+ "user fails, or the option itself is disabled."
124
+ msgstr ""
125
+ "Geef de naam van een stad of land op als start locatie onder de \"Kaart "
126
+ "Instellingen\". Deze locatie wordt alleen maar gebruikt als het automatische "
127
+ "achterhalen van de gebruikers locatie mislukt, of het automatische "
128
+ "achterhalen is uitgeschakeld."
129
+
130
+ #: admin/class-admin.php:634
131
+ #, php-format
132
+ msgid ""
133
+ "Before adding the [wpsl] shortcode to a page, please don't forget to define "
134
+ "a start point on the %ssettings%s page."
135
+ msgstr ""
136
+ "Vergeet niet voordat je de [wpsl] shortcode op een pagina plaatst, om een "
137
+ "start locatie op te geven op de %sinstellingen%s pagina."
138
+
139
+ #: admin/class-admin.php:634
140
+ msgid "Dismiss"
141
+ msgstr "Sluiten"
142
+
143
+ #: admin/class-admin.php:886
144
+ msgid ""
145
+ "The Google Geocoding API returned no results for the store location. Please "
146
+ "change the location and try again."
147
+ msgstr ""
148
+ "De Google Geocoding API gaf geen resultaten terug voor deze locatie. Wijzig "
149
+ "de locatie details en probeer het nog een keer."
150
+
151
+ #: admin/class-admin.php:889
152
+ #, php-format
153
+ msgid ""
154
+ "You have reached the daily allowed geocoding limit, you can read more <a "
155
+ "href=\"%s\">here</a>."
156
+ msgstr ""
157
+ "Je hebt de dagelijkse toegestane geocoding limiet bereikt, je kan er <a href="
158
+ "\"%s\">hier</a> meer over lezen."
159
+
160
+ #: admin/class-admin.php:892
161
+ msgid ""
162
+ "The Google Geocoding API failed to return valid data, please try again later."
163
+ msgstr ""
164
+ "De Google Geocoding API geeft ongeldige data terug, probeer het nog een keer."
165
+
166
+ #: admin/class-admin.php:972
167
+ msgid "Start location marker:"
168
+ msgstr "Start locatie marker:"
169
+
170
+ #: admin/class-admin.php:974
171
+ msgid "Store location marker:"
172
+ msgstr "Winkel locatie marker:"
173
+
174
+ #: admin/class-admin.php:1134 wp-store-locator.php:313
175
+ msgid "Default"
176
+ msgstr "Standaard"
177
+
178
+ #: admin/class-admin.php:1242
179
+ msgid "In the store listings"
180
+ msgstr "In the locatie lijst"
181
+
182
+ #: admin/class-admin.php:1243
183
+ msgid "In the info window on the map"
184
+ msgstr "In de info window op de kaart"
185
+
186
+ #: admin/class-admin.php:1269
187
+ msgid "Select your language"
188
+ msgstr "Kies uw taal"
189
+
190
+ #: admin/class-admin.php:1270
191
+ msgid "English"
192
+ msgstr "Engels"
193
+
194
+ #: admin/class-admin.php:1271
195
+ msgid "Arabic"
196
+ msgstr "Arabisch"
197
+
198
+ #: admin/class-admin.php:1272
199
+ msgid "Basque"
200
+ msgstr "Bask"
201
+
202
+ #: admin/class-admin.php:1273
203
+ msgid "Bulgarian"
204
+ msgstr "Bulgaars"
205
+
206
+ #: admin/class-admin.php:1274
207
+ msgid "Bengali"
208
+ msgstr "Bengali"
209
+
210
+ #: admin/class-admin.php:1275
211
+ msgid "Catalan"
212
+ msgstr "Catalaans"
213
+
214
+ #: admin/class-admin.php:1276
215
+ msgid "Czech"
216
+ msgstr "Tjechische"
217
+
218
+ #: admin/class-admin.php:1277
219
+ msgid "Danish"
220
+ msgstr "Deens"
221
+
222
+ #: admin/class-admin.php:1278
223
+ msgid "German"
224
+ msgstr "Duits"
225
+
226
+ #: admin/class-admin.php:1279
227
+ msgid "Greek"
228
+ msgstr "Grieks"
229
+
230
+ #: admin/class-admin.php:1280
231
+ msgid "English (Australian)"
232
+ msgstr "Engels (Australisch)"
233
+
234
+ #: admin/class-admin.php:1281
235
+ msgid "English (Great Britain)"
236
+ msgstr "Engels (Verenigd Koningkrijk)"
237
+
238
+ #: admin/class-admin.php:1282
239
+ msgid "Spanish"
240
+ msgstr "Spaans"
241
+
242
+ #: admin/class-admin.php:1283
243
+ msgid "Farsi"
244
+ msgstr "Farsi"
245
+
246
+ #: admin/class-admin.php:1284
247
+ msgid "Finnish"
248
+ msgstr "Fins"
249
+
250
+ #: admin/class-admin.php:1285
251
+ msgid "Filipino"
252
+ msgstr "Filipijns"
253
+
254
+ #: admin/class-admin.php:1286
255
+ msgid "French"
256
+ msgstr "Frans"
257
+
258
+ #: admin/class-admin.php:1287
259
+ msgid "Galician"
260
+ msgstr "Gallisch"
261
+
262
+ #: admin/class-admin.php:1288
263
+ msgid "Gujarati"
264
+ msgstr "Gujurati"
265
+
266
+ #: admin/class-admin.php:1289
267
+ msgid "Hindi"
268
+ msgstr "Hindi"
269
+
270
+ #: admin/class-admin.php:1290
271
+ msgid "Croatian"
272
+ msgstr "Kroaats"
273
+
274
+ #: admin/class-admin.php:1291
275
+ msgid "Hungarian"
276
+ msgstr "Hongaars"
277
+
278
+ #: admin/class-admin.php:1292
279
+ msgid "Indonesian"
280
+ msgstr "Indonesisch"
281
+
282
+ #: admin/class-admin.php:1293
283
+ msgid "Italian"
284
+ msgstr "Italiaans"
285
+
286
+ #: admin/class-admin.php:1294
287
+ msgid "Hebrew"
288
+ msgstr "Hebreeuwse"
289
+
290
+ #: admin/class-admin.php:1295
291
+ msgid "Japanese"
292
+ msgstr "Japans"
293
+
294
+ #: admin/class-admin.php:1296
295
+ msgid "Kannada"
296
+ msgstr "Kannada"
297
+
298
+ #: admin/class-admin.php:1297
299
+ msgid "Korean"
300
+ msgstr "Koreaans"
301
+
302
+ #: admin/class-admin.php:1298
303
+ msgid "Lithuanian"
304
+ msgstr "Litouws"
305
+
306
+ #: admin/class-admin.php:1299
307
+ msgid "Latvian"
308
+ msgstr "Lets"
309
+
310
+ #: admin/class-admin.php:1300
311
+ msgid "Malayalam"
312
+ msgstr "Malayalam"
313
+
314
+ #: admin/class-admin.php:1301
315
+ msgid "Marathi"
316
+ msgstr "Marathi"
317
+
318
+ #: admin/class-admin.php:1302
319
+ msgid "Dutch"
320
+ msgstr "Nederlands"
321
+
322
+ #: admin/class-admin.php:1303
323
+ msgid "Norwegian"
324
+ msgstr "Noors"
325
+
326
+ #: admin/class-admin.php:1304
327
+ msgid "Norwegian Nynorsk"
328
+ msgstr "Noors Nynorsk"
329
+
330
+ #: admin/class-admin.php:1305
331
+ msgid "Polish"
332
+ msgstr "Pools"
333
+
334
+ #: admin/class-admin.php:1306
335
+ msgid "Portuguese"
336
+ msgstr "Portugees"
337
+
338
+ #: admin/class-admin.php:1307
339
+ msgid "Portuguese (Brazil)"
340
+ msgstr "Portugees (Brazilië)"
341
+
342
+ #: admin/class-admin.php:1308
343
+ msgid "Portuguese (Portugal)"
344
+ msgstr "Portugees (Portugal)"
345
+
346
+ #: admin/class-admin.php:1309
347
+ msgid "Romanian"
348
+ msgstr "Roemeens"
349
+
350
+ #: admin/class-admin.php:1310
351
+ msgid "Russian"
352
+ msgstr "Russisch"
353
+
354
+ #: admin/class-admin.php:1311
355
+ msgid "Slovak"
356
+ msgstr "Slowaaks"
357
+
358
+ #: admin/class-admin.php:1312
359
+ msgid "Slovenian"
360
+ msgstr "Sloveens"
361
+
362
+ #: admin/class-admin.php:1313
363
+ msgid "Serbian"
364
+ msgstr "Servisch"
365
+
366
+ #: admin/class-admin.php:1314
367
+ msgid "Swedish"
368
+ msgstr "Zweeds"
369
+
370
+ #: admin/class-admin.php:1315
371
+ msgid "Tagalog"
372
+ msgstr "Tagalog"
373
+
374
+ #: admin/class-admin.php:1316
375
+ msgid "Tamil"
376
+ msgstr "Tamil"
377
+
378
+ #: admin/class-admin.php:1317
379
+ msgid "Telugu"
380
+ msgstr "Telugu"
381
+
382
+ #: admin/class-admin.php:1318
383
+ msgid "Thai"
384
+ msgstr "Thai"
385
+
386
+ #: admin/class-admin.php:1319
387
+ msgid "Turkish"
388
+ msgstr "Turks"
389
+
390
+ #: admin/class-admin.php:1320
391
+ msgid "Ukrainian"
392
+ msgstr "Oekraïens"
393
+
394
+ #: admin/class-admin.php:1321
395
+ msgid "Vietnamese"
396
+ msgstr "Vietnamees"
397
+
398
+ #: admin/class-admin.php:1322
399
+ msgid "Chinese (Simplified)"
400
+ msgstr "Chinees (Vereenvoudigd)"
401
+
402
+ #: admin/class-admin.php:1323
403
+ msgid "Chinese (Traditional)"
404
+ msgstr "Chinees (Traditioneel)"
405
+
406
+ #: admin/class-admin.php:1328
407
+ msgid "Select your region"
408
+ msgstr "Kies uw regio"
409
+
410
+ #: admin/class-admin.php:1329
411
+ msgid "Afghanistan"
412
+ msgstr "Afghanistan"
413
+
414
+ #: admin/class-admin.php:1330
415
+ msgid "Albania"
416
+ msgstr "Albanië"
417
+
418
+ #: admin/class-admin.php:1331
419
+ msgid "Algeria"
420
+ msgstr "Algerian"
421
+
422
+ #: admin/class-admin.php:1332
423
+ msgid "American Samoa"
424
+ msgstr "Amerikaans Samoa"
425
+
426
+ #: admin/class-admin.php:1333
427
+ msgid "Andorra"
428
+ msgstr "Andorra"
429
+
430
+ #: admin/class-admin.php:1334
431
+ msgid "Anguilla"
432
+ msgstr "Anguilla"
433
+
434
+ #: admin/class-admin.php:1335
435
+ msgid "Angola"
436
+ msgstr "Angola"
437
+
438
+ #: admin/class-admin.php:1336
439
+ msgid "Antigua and Barbuda"
440
+ msgstr "Antigua en Barbuda"
441
+
442
+ #: admin/class-admin.php:1337
443
+ msgid "Argentina"
444
+ msgstr "Argentinië"
445
+
446
+ #: admin/class-admin.php:1338
447
+ msgid "Armenia"
448
+ msgstr "Armenia"
449
+
450
+ #: admin/class-admin.php:1339
451
+ msgid "Aruba"
452
+ msgstr "Aruba"
453
+
454
+ #: admin/class-admin.php:1340
455
+ msgid "Australia"
456
+ msgstr "Australië"
457
+
458
+ #: admin/class-admin.php:1341
459
+ msgid "Austria"
460
+ msgstr "Oostenrijk"
461
+
462
+ #: admin/class-admin.php:1342
463
+ msgid "Azerbaijan"
464
+ msgstr "Azerbeidzjan"
465
+
466
+ #: admin/class-admin.php:1343
467
+ msgid "Bahamas"
468
+ msgstr "Bahamas"
469
+
470
+ #: admin/class-admin.php:1344
471
+ msgid "Bahrain"
472
+ msgstr "Bahrein"
473
+
474
+ #: admin/class-admin.php:1345
475
+ msgid "Bangladesh"
476
+ msgstr "Bangladesh"
477
+
478
+ #: admin/class-admin.php:1346
479
+ msgid "Barbados"
480
+ msgstr "Barbados"
481
+
482
+ #: admin/class-admin.php:1347
483
+ msgid "Belarus"
484
+ msgstr "Wit-Rusland"
485
+
486
+ #: admin/class-admin.php:1348
487
+ msgid "Belgium"
488
+ msgstr "België"
489
+
490
+ #: admin/class-admin.php:1349
491
+ msgid "Belize"
492
+ msgstr "Belize"
493
+
494
+ #: admin/class-admin.php:1350
495
+ msgid "Benin"
496
+ msgstr "Benin"
497
+
498
+ #: admin/class-admin.php:1351
499
+ msgid "Bermuda"
500
+ msgstr "Bermuda"
501
+
502
+ #: admin/class-admin.php:1352
503
+ msgid "Bhutan"
504
+ msgstr "Bhutan"
505
+
506
+ #: admin/class-admin.php:1353
507
+ msgid "Bolivia"
508
+ msgstr "Bolivia"
509
+
510
+ #: admin/class-admin.php:1354
511
+ msgid "Bosnia and Herzegovina"
512
+ msgstr "Bosnia en Herzegovina"
513
+
514
+ #: admin/class-admin.php:1355
515
+ msgid "Botswana"
516
+ msgstr "Botswana"
517
+
518
+ #: admin/class-admin.php:1356
519
+ msgid "Brazil"
520
+ msgstr "Brazilië"
521
+
522
+ #: admin/class-admin.php:1357
523
+ msgid "British Indian Ocean Territory"
524
+ msgstr "Brits Indische Oceaanterritorium"
525
+
526
+ #: admin/class-admin.php:1358
527
+ msgid "Brunei"
528
+ msgstr "Brunei"
529
+
530
+ #: admin/class-admin.php:1359
531
+ msgid "Bulgaria"
532
+ msgstr "Bulgarije"
533
+
534
+ #: admin/class-admin.php:1360
535
+ msgid "Burkina Faso"
536
+ msgstr "Burkina Faso"
537
+
538
+ #: admin/class-admin.php:1361
539
+ msgid "Burundi"
540
+ msgstr "Burundi"
541
+
542
+ #: admin/class-admin.php:1362
543
+ msgid "Cambodia"
544
+ msgstr "Cambodja"
545
+
546
+ #: admin/class-admin.php:1363
547
+ msgid "Cameroon"
548
+ msgstr "Kameroen"
549
+
550
+ #: admin/class-admin.php:1364
551
+ msgid "Canada"
552
+ msgstr "Canada"
553
+
554
+ #: admin/class-admin.php:1365
555
+ msgid "Cape Verde"
556
+ msgstr "Kaapverdië"
557
+
558
+ #: admin/class-admin.php:1366
559
+ msgid "Cayman Islands"
560
+ msgstr "Kaaimaneilanden"
561
+
562
+ #: admin/class-admin.php:1367
563
+ msgid "Central African Republic"
564
+ msgstr "Centraal-Afrikaanse Republiek"
565
+
566
+ #: admin/class-admin.php:1368
567
+ msgid "Chad"
568
+ msgstr "Chad"
569
+
570
+ #: admin/class-admin.php:1369
571
+ msgid "Chile"
572
+ msgstr "Chili"
573
+
574
+ #: admin/class-admin.php:1370
575
+ msgid "China"
576
+ msgstr "China"
577
+
578
+ #: admin/class-admin.php:1371
579
+ msgid "Christmas Island"
580
+ msgstr "Christmaseiland"
581
+
582
+ #: admin/class-admin.php:1372
583
+ msgid "Cocos Islands"
584
+ msgstr "Cocoseilanden"
585
+
586
+ #: admin/class-admin.php:1373
587
+ msgid "Colombia"
588
+ msgstr "Colombia"
589
+
590
+ #: admin/class-admin.php:1374
591
+ msgid "Comoros"
592
+ msgstr "Comoren"
593
+
594
+ #: admin/class-admin.php:1375
595
+ msgid "Congo"
596
+ msgstr "Congo"
597
+
598
+ #: admin/class-admin.php:1376
599
+ msgid "Costa Rica"
600
+ msgstr "Costa Rica"
601
+
602
+ #: admin/class-admin.php:1377
603
+ msgid "Côte d'Ivoire"
604
+ msgstr "Ivoorkust"
605
+
606
+ #: admin/class-admin.php:1378
607
+ msgid "Croatia"
608
+ msgstr "Kroatië"
609
+
610
+ #: admin/class-admin.php:1379
611
+ msgid "Cuba"
612
+ msgstr "Cuba"
613
+
614
+ #: admin/class-admin.php:1380
615
+ msgid "Czech Republic"
616
+ msgstr "Tsjechië"
617
+
618
+ #: admin/class-admin.php:1381
619
+ msgid "Denmark"
620
+ msgstr "Denemarken"
621
+
622
+ #: admin/class-admin.php:1382
623
+ msgid "Djibouti"
624
+ msgstr "Djibouti"
625
+
626
+ #: admin/class-admin.php:1383
627
+ msgid "Democratic Republic of the Congo"
628
+ msgstr "Democratische Republiek Congo"
629
+
630
+ #: admin/class-admin.php:1384
631
+ msgid "Dominica"
632
+ msgstr "Dominica"
633
+
634
+ #: admin/class-admin.php:1385
635
+ msgid "Dominican Republic"
636
+ msgstr "Dominicaanse Republiek"
637
+
638
+ #: admin/class-admin.php:1386
639
+ msgid "Ecuador"
640
+ msgstr "Ecuador"
641
+
642
+ #: admin/class-admin.php:1387
643
+ msgid "Egypt"
644
+ msgstr "Egypte"
645
+
646
+ #: admin/class-admin.php:1388
647
+ msgid "El Salvador"
648
+ msgstr "El Salvador"
649
+
650
+ #: admin/class-admin.php:1389
651
+ msgid "Equatorial Guinea"
652
+ msgstr "Equatoriaal-Guinea"
653
+
654
+ #: admin/class-admin.php:1390
655
+ msgid "Eritrea"
656
+ msgstr "Eritrea"
657
+
658
+ #: admin/class-admin.php:1391
659
+ msgid "Estonia"
660
+ msgstr "Estland"
661
+
662
+ #: admin/class-admin.php:1392
663
+ msgid "Ethiopia"
664
+ msgstr "Ethiopië"
665
+
666
+ #: admin/class-admin.php:1393
667
+ msgid "Fiji"
668
+ msgstr "Fiji"
669
+
670
+ #: admin/class-admin.php:1394
671
+ msgid "Finland"
672
+ msgstr "Finland"
673
+
674
+ #: admin/class-admin.php:1395
675
+ msgid "France"
676
+ msgstr "Frankrijk"
677
+
678
+ #: admin/class-admin.php:1396
679
+ msgid "French Guiana"
680
+ msgstr "Frans Guyana"
681
+
682
+ #: admin/class-admin.php:1397
683
+ msgid "Gabon"
684
+ msgstr "Gabon"
685
+
686
+ #: admin/class-admin.php:1398
687
+ msgid "Gambia"
688
+ msgstr "Gambia"
689
+
690
+ #: admin/class-admin.php:1399
691
+ msgid "Germany"
692
+ msgstr "Duitsland"
693
+
694
+ #: admin/class-admin.php:1400
695
+ msgid "Ghana"
696
+ msgstr "Ghana"
697
+
698
+ #: admin/class-admin.php:1401
699
+ msgid "Greenland"
700
+ msgstr "Groenland"
701
+
702
+ #: admin/class-admin.php:1402
703
+ msgid "Greece"
704
+ msgstr "Griekenland"
705
+
706
+ #: admin/class-admin.php:1403
707
+ msgid "Grenada"
708
+ msgstr "Grenada"
709
+
710
+ #: admin/class-admin.php:1404
711
+ msgid "Guam"
712
+ msgstr "Guam"
713
+
714
+ #: admin/class-admin.php:1405
715
+ msgid "Guadeloupe"
716
+ msgstr "Guadeloupe"
717
+
718
+ #: admin/class-admin.php:1406
719
+ msgid "Guatemala"
720
+ msgstr "Guatemala"
721
+
722
+ #: admin/class-admin.php:1407
723
+ msgid "Guinea"
724
+ msgstr "Guinee"
725
+
726
+ #: admin/class-admin.php:1408
727
+ msgid "Guinea-Bissau"
728
+ msgstr "Guinee-Bissau"
729
+
730
+ #: admin/class-admin.php:1409
731
+ msgid "Haiti"
732
+ msgstr "Haïti"
733
+
734
+ #: admin/class-admin.php:1410
735
+ msgid "Honduras"
736
+ msgstr "Honduras"
737
+
738
+ #: admin/class-admin.php:1411
739
+ msgid "Hong Kong"
740
+ msgstr "Hong Kong"
741
+
742
+ #: admin/class-admin.php:1412
743
+ msgid "Hungary"
744
+ msgstr "Hongarije"
745
+
746
+ #: admin/class-admin.php:1413
747
+ msgid "Iceland"
748
+ msgstr "IJsland"
749
+
750
+ #: admin/class-admin.php:1414
751
+ msgid "India"
752
+ msgstr "India"
753
+
754
+ #: admin/class-admin.php:1415
755
+ msgid "Indonesia"
756
+ msgstr "Indonesië"
757
+
758
+ #: admin/class-admin.php:1416
759
+ msgid "Iran"
760
+ msgstr "Iran"
761
+
762
+ #: admin/class-admin.php:1417
763
+ msgid "Iraq"
764
+ msgstr "Irak"
765
+
766
+ #: admin/class-admin.php:1418
767
+ msgid "Ireland"
768
+ msgstr "Ierland"
769
+
770
+ #: admin/class-admin.php:1419
771
+ msgid "Israel"
772
+ msgstr "Israël"
773
+
774
+ #: admin/class-admin.php:1420
775
+ msgid "Italy"
776
+ msgstr "Italië"
777
+
778
+ #: admin/class-admin.php:1421
779
+ msgid "Jamaica"
780
+ msgstr "Jamaica"
781
+
782
+ #: admin/class-admin.php:1422
783
+ msgid "Japan"
784
+ msgstr "Japan"
785
+
786
+ #: admin/class-admin.php:1423
787
+ msgid "Jordan"
788
+ msgstr "Jordanië"
789
+
790
+ #: admin/class-admin.php:1424
791
+ msgid "Kazakhstan"
792
+ msgstr "Kazachstan"
793
+
794
+ #: admin/class-admin.php:1425
795
+ msgid "Kenya"
796
+ msgstr "Kenia"
797
+
798
+ #: admin/class-admin.php:1426
799
+ msgid "Kuwait"
800
+ msgstr "Koeweit"
801
+
802
+ #: admin/class-admin.php:1427
803
+ msgid "Kyrgyzstan"
804
+ msgstr "Kirgizië"
805
+
806
+ #: admin/class-admin.php:1428
807
+ msgid "Laos"
808
+ msgstr "Laos"
809
+
810
+ #: admin/class-admin.php:1429
811
+ msgid "Latvia"
812
+ msgstr "Letland"
813
+
814
+ #: admin/class-admin.php:1430
815
+ msgid "Lebanon"
816
+ msgstr "Libanon"
817
+
818
+ #: admin/class-admin.php:1431
819
+ msgid "Lesotho"
820
+ msgstr "Lesotho"
821
+
822
+ #: admin/class-admin.php:1432
823
+ msgid "Liberia"
824
+ msgstr "Liberia"
825
+
826
+ #: admin/class-admin.php:1433
827
+ msgid "Libya"
828
+ msgstr "Libië"
829
+
830
+ #: admin/class-admin.php:1434
831
+ msgid "Liechtenstein"
832
+ msgstr "Liechtenstein"
833
+
834
+ #: admin/class-admin.php:1435
835
+ msgid "Lithuania"
836
+ msgstr "Litouwen"
837
+
838
+ #: admin/class-admin.php:1436
839
+ msgid "Luxembourg"
840
+ msgstr "Luxemburg"
841
+
842
+ #: admin/class-admin.php:1437
843
+ msgid "Macau"
844
+ msgstr "Macau"
845
+
846
+ #: admin/class-admin.php:1438
847
+ msgid "Macedonia"
848
+ msgstr "Macedonië"
849
+
850
+ #: admin/class-admin.php:1439
851
+ msgid "Madagascar"
852
+ msgstr "Madagascar"
853
+
854
+ #: admin/class-admin.php:1440
855
+ msgid "Malawi"
856
+ msgstr "Malawi"
857
+
858
+ #: admin/class-admin.php:1441
859
+ msgid "Malaysia "
860
+ msgstr "Maleisie"
861
+
862
+ #: admin/class-admin.php:1442
863
+ msgid "Mali"
864
+ msgstr "Mali"
865
+
866
+ #: admin/class-admin.php:1443
867
+ msgid "Marshall Islands"
868
+ msgstr "Marshalleilanden"
869
+
870
+ #: admin/class-admin.php:1444
871
+ msgid "Martinique"
872
+ msgstr "Martinique"
873
+
874
+ #: admin/class-admin.php:1445
875
+ msgid "Mauritania"
876
+ msgstr "Mauritanië"
877
+
878
+ #: admin/class-admin.php:1446
879
+ msgid "Mauritius"
880
+ msgstr "Mauritius"
881
+
882
+ #: admin/class-admin.php:1447
883
+ msgid "Mexico"
884
+ msgstr "Mexico"
885
+
886
+ #: admin/class-admin.php:1448
887
+ msgid "Micronesia"
888
+ msgstr "Micronesia"
889
+
890
+ #: admin/class-admin.php:1449
891
+ msgid "Moldova"
892
+ msgstr "Moldavië"
893
+
894
+ #: admin/class-admin.php:1450
895
+ msgid "Monaco"
896
+ msgstr "Monaco"
897
+
898
+ #: admin/class-admin.php:1451
899
+ msgid "Mongolia"
900
+ msgstr "Mongolië"
901
+
902
+ #: admin/class-admin.php:1452
903
+ msgid "Montenegro"
904
+ msgstr "Montenegro"
905
+
906
+ #: admin/class-admin.php:1453
907
+ msgid "Montserrat"
908
+ msgstr "Montserrat "
909
+
910
+ #: admin/class-admin.php:1454
911
+ msgid "Morocco"
912
+ msgstr "Marokko"
913
+
914
+ #: admin/class-admin.php:1455
915
+ msgid "Mozambique"
916
+ msgstr "Mozambique"
917
+
918
+ #: admin/class-admin.php:1456
919
+ msgid "Myanmar"
920
+ msgstr "Myanmar"
921
+
922
+ #: admin/class-admin.php:1457
923
+ msgid "Namibia"
924
+ msgstr "Namibië"
925
+
926
+ #: admin/class-admin.php:1458
927
+ msgid "Nauru"
928
+ msgstr "Nauru"
929
+
930
+ #: admin/class-admin.php:1459
931
+ msgid "Nepal"
932
+ msgstr "Nepal"
933
+
934
+ #: admin/class-admin.php:1460
935
+ msgid "Netherlands"
936
+ msgstr "Nederland"
937
+
938
+ #: admin/class-admin.php:1461
939
+ msgid "Netherlands Antilles"
940
+ msgstr "Nederlandse Antillen"
941
+
942
+ #: admin/class-admin.php:1462
943
+ msgid "New Zealand"
944
+ msgstr "Nieuw Zeeland"
945
+
946
+ #: admin/class-admin.php:1463
947
+ msgid "Nicaragua"
948
+ msgstr "Nicaragua"
949
+
950
+ #: admin/class-admin.php:1464
951
+ msgid "Niger"
952
+ msgstr "Niger"
953
+
954
+ #: admin/class-admin.php:1465
955
+ msgid "Nigeria"
956
+ msgstr "Nigeria"
957
+
958
+ #: admin/class-admin.php:1466
959
+ msgid "Niue"
960
+ msgstr "Niue"
961
+
962
+ #: admin/class-admin.php:1467
963
+ msgid "Northern Mariana Islands"
964
+ msgstr "Noordelijke Marianen"
965
+
966
+ #: admin/class-admin.php:1468
967
+ msgid "Norway"
968
+ msgstr "Noorwegen"
969
+
970
+ #: admin/class-admin.php:1469
971
+ msgid "Oman"
972
+ msgstr "Oman"
973
+
974
+ #: admin/class-admin.php:1470
975
+ msgid "Pakistan"
976
+ msgstr "Pakistan"
977
+
978
+ #: admin/class-admin.php:1471
979
+ msgid "Panama"
980
+ msgstr "Panama"
981
+
982
+ #: admin/class-admin.php:1472
983
+ msgid "Papua New Guinea"
984
+ msgstr "Papoea-Nieuw-Guinea"
985
+
986
+ #: admin/class-admin.php:1473
987
+ msgid "Paraguay"
988
+ msgstr "Paraguay"
989
+
990
+ #: admin/class-admin.php:1474
991
+ msgid "Peru"
992
+ msgstr "Peru"
993
+
994
+ #: admin/class-admin.php:1475
995
+ msgid "Philippines"
996
+ msgstr "Filipijnen"
997
+
998
+ #: admin/class-admin.php:1476
999
+ msgid "Pitcairn Islands"
1000
+ msgstr "Pitcairneilanden"
1001
+
1002
+ #: admin/class-admin.php:1477
1003
+ msgid "Poland"
1004
+ msgstr "Polen"
1005
+
1006
+ #: admin/class-admin.php:1478
1007
+ msgid "Portugal"
1008
+ msgstr "Portugal"
1009
+
1010
+ #: admin/class-admin.php:1479
1011
+ msgid "Qatar"
1012
+ msgstr "Qatar"
1013
+
1014
+ #: admin/class-admin.php:1480
1015
+ msgid "Reunion"
1016
+ msgstr "Réunion"
1017
+
1018
+ #: admin/class-admin.php:1481
1019
+ msgid "Romania"
1020
+ msgstr "Roemenië"
1021
+
1022
+ #: admin/class-admin.php:1482
1023
+ msgid "Russia"
1024
+ msgstr "Rusland"
1025
+
1026
+ #: admin/class-admin.php:1483
1027
+ msgid "Rwanda"
1028
+ msgstr "Rwanda"
1029
+
1030
+ #: admin/class-admin.php:1484
1031
+ msgid "Saint Helena"
1032
+ msgstr "Sint-Helena"
1033
+
1034
+ #: admin/class-admin.php:1485
1035
+ msgid "Saint Kitts and Nevis"
1036
+ msgstr "Saint Kitts en Nevis"
1037
+
1038
+ #: admin/class-admin.php:1486
1039
+ msgid "Saint Vincent and the Grenadines"
1040
+ msgstr "Saint Vincent en de Grenadines"
1041
+
1042
+ #: admin/class-admin.php:1487
1043
+ msgid "Saint Lucia"
1044
+ msgstr "Saint Lucia"
1045
+
1046
+ #: admin/class-admin.php:1488
1047
+ msgid "Samoa"
1048
+ msgstr "Samoa"
1049
+
1050
+ #: admin/class-admin.php:1489
1051
+ msgid "San Marino"
1052
+ msgstr "San Marino"
1053
+
1054
+ #: admin/class-admin.php:1490
1055
+ msgid "São Tomé and Príncipe"
1056
+ msgstr "Sao Tomé en Principe"
1057
+
1058
+ #: admin/class-admin.php:1491
1059
+ msgid "Saudi Arabia"
1060
+ msgstr "Saoedi-Arabië"
1061
+
1062
+ #: admin/class-admin.php:1492
1063
+ msgid "Senegal"
1064
+ msgstr "Senegal"
1065
+
1066
+ #: admin/class-admin.php:1493
1067
+ msgid "Serbia"
1068
+ msgstr "Servië"
1069
+
1070
+ #: admin/class-admin.php:1494
1071
+ msgid "Seychelles"
1072
+ msgstr "Seychellen"
1073
+
1074
+ #: admin/class-admin.php:1495
1075
+ msgid "Sierra Leone"
1076
+ msgstr "Sierra Leone"
1077
+
1078
+ #: admin/class-admin.php:1496
1079
+ msgid "Singapore"
1080
+ msgstr "Singapore"
1081
+
1082
+ #: admin/class-admin.php:1497
1083
+ msgid "Slovakia"
1084
+ msgstr "Slowakije"
1085
+
1086
+ #: admin/class-admin.php:1498
1087
+ msgid "Solomon Islands"
1088
+ msgstr "Salomonseilanden"
1089
+
1090
+ #: admin/class-admin.php:1499
1091
+ msgid "Somalia"
1092
+ msgstr "Somalie"
1093
+
1094
+ #: admin/class-admin.php:1500
1095
+ msgid "South Africa"
1096
+ msgstr "Zuid Afrika"
1097
+
1098
+ #: admin/class-admin.php:1501
1099
+ msgid "South Korea"
1100
+ msgstr "Zuid Korea"
1101
+
1102
+ #: admin/class-admin.php:1502
1103
+ msgid "Spain"
1104
+ msgstr "Spanje"
1105
+
1106
+ #: admin/class-admin.php:1503
1107
+ msgid "Sri Lanka"
1108
+ msgstr "Sri Lanka"
1109
+
1110
+ #: admin/class-admin.php:1504
1111
+ msgid "Sudan"
1112
+ msgstr "Sudan"
1113
+
1114
+ #: admin/class-admin.php:1505
1115
+ msgid "Swaziland"
1116
+ msgstr "Swaziland "
1117
+
1118
+ #: admin/class-admin.php:1506
1119
+ msgid "Sweden"
1120
+ msgstr "Zweden"
1121
+
1122
+ #: admin/class-admin.php:1507
1123
+ msgid "Switzerland"
1124
+ msgstr "Zwitserland"
1125
+
1126
+ #: admin/class-admin.php:1508
1127
+ msgid "Syria"
1128
+ msgstr "Syrië"
1129
+
1130
+ #: admin/class-admin.php:1509
1131
+ msgid "Taiwan"
1132
+ msgstr "Taiwan"
1133
+
1134
+ #: admin/class-admin.php:1510
1135
+ msgid "Tajikistan"
1136
+ msgstr "Tajikistan"
1137
+
1138
+ #: admin/class-admin.php:1511
1139
+ msgid "Tanzania"
1140
+ msgstr "Tanzania"
1141
+
1142
+ #: admin/class-admin.php:1512
1143
+ msgid "Thailand"
1144
+ msgstr "Thailand"
1145
+
1146
+ #: admin/class-admin.php:1513
1147
+ msgid "Timor-Leste"
1148
+ msgstr "Oost-Timor"
1149
+
1150
+ #: admin/class-admin.php:1514
1151
+ msgid "Tokelau"
1152
+ msgstr "Tokelau"
1153
+
1154
+ #: admin/class-admin.php:1515
1155
+ msgid "Togo"
1156
+ msgstr "Togo"
1157
+
1158
+ #: admin/class-admin.php:1516
1159
+ msgid "Tonga"
1160
+ msgstr "Tonga"
1161
+
1162
+ #: admin/class-admin.php:1517
1163
+ msgid "Trinidad and Tobago"
1164
+ msgstr "Trinidad en Tobago"
1165
+
1166
+ #: admin/class-admin.php:1518
1167
+ msgid "Tunisia"
1168
+ msgstr "Tunesië"
1169
+
1170
+ #: admin/class-admin.php:1519
1171
+ msgid "Turkey"
1172
+ msgstr "Turkije"
1173
+
1174
+ #: admin/class-admin.php:1520
1175
+ msgid "Turkmenistan"
1176
+ msgstr "Turkmenistan"
1177
+
1178
+ #: admin/class-admin.php:1521
1179
+ msgid "Tuvalu"
1180
+ msgstr "Tuvalu"
1181
+
1182
+ #: admin/class-admin.php:1522
1183
+ msgid "Uganda"
1184
+ msgstr "Uganda"
1185
+
1186
+ #: admin/class-admin.php:1523
1187
+ msgid "Ukraine"
1188
+ msgstr "Oekraïne"
1189
+
1190
+ #: admin/class-admin.php:1524
1191
+ msgid "United Arab Emirates"
1192
+ msgstr "Verenigde Arabische Emiraten"
1193
+
1194
+ #: admin/class-admin.php:1525
1195
+ msgid "United Kingdom"
1196
+ msgstr "Verenigd Koninkrijk"
1197
+
1198
+ #: admin/class-admin.php:1526
1199
+ msgid "United States"
1200
+ msgstr "Verenigde Staten"
1201
+
1202
+ #: admin/class-admin.php:1527
1203
+ msgid "Uruguay"
1204
+ msgstr "Uruguay"
1205
+
1206
+ #: admin/class-admin.php:1528
1207
+ msgid "Uzbekistan"
1208
+ msgstr "Uzbekistan"
1209
+
1210
+ #: admin/class-admin.php:1529
1211
+ msgid "Wallis Futuna"
1212
+ msgstr "Wallis en Futuna"
1213
+
1214
+ #: admin/class-admin.php:1530
1215
+ msgid "Venezuela"
1216
+ msgstr "Venezuela"
1217
+
1218
+ #: admin/class-admin.php:1531
1219
+ msgid "Vietnam"
1220
+ msgstr "Vietnam"
1221
+
1222
+ #: admin/class-admin.php:1532
1223
+ msgid "Yemen"
1224
+ msgstr "Yemen"
1225
+
1226
+ #: admin/class-admin.php:1533
1227
+ msgid "Zambia"
1228
+ msgstr "Zambia"
1229
+
1230
+ #: admin/class-admin.php:1534
1231
+ msgid "Zimbabwe"
1232
+ msgstr "Zimbabwe"
1233
+
1234
+ #: admin/class-admin.php:1607
1235
+ msgid "Cannot determine the address at this location."
1236
+ msgstr "Er kan geen adres gevonden worden voor deze locatie."
1237
+
1238
+ #: admin/class-admin.php:1608
1239
+ msgid "Geocode was not successful for the following reason: "
1240
+ msgstr "Geocode was niet succesvol om de volgende reden:"
1241
+
1242
+ #: admin/class-admin.php:1609
1243
+ msgid "Security check failed, reload the page and try again."
1244
+ msgstr ""
1245
+ "Beveiligings controle mislukt, herlaad de pagina en probeer het nog een keer."
1246
+
1247
+ #: admin/class-store-overview.php:30
1248
+ msgid "Store"
1249
+ msgstr "Locatie"
1250
+
1251
+ #: admin/class-store-overview.php:65
1252
+ msgid "No stores found"
1253
+ msgstr "Geen locaties gevonden"
1254
+
1255
+ #: admin/class-store-overview.php:95
1256
+ msgid "Active"
1257
+ msgstr "Actief"
1258
+
1259
+ #: admin/class-store-overview.php:95
1260
+ msgid "Inactive"
1261
+ msgstr "Niet actief"
1262
+
1263
+ #: admin/class-store-overview.php:97
1264
+ msgid "Edit"
1265
+ msgstr "Bewerk"
1266
+
1267
+ #: admin/class-store-overview.php:97 admin/class-store-overview.php:171
1268
+ #: admin/class-store-overview.php:420
1269
+ msgid "Delete"
1270
+ msgstr "Verwijder"
1271
+
1272
+ #: admin/class-store-overview.php:135
1273
+ msgid "ID"
1274
+ msgstr "ID"
1275
+
1276
+ #: admin/class-store-overview.php:136
1277
+ msgid "Thumbnail"
1278
+ msgstr "Afbeelding"
1279
+
1280
+ #: admin/class-store-overview.php:137
1281
+ msgid "Name"
1282
+ msgstr "Naam"
1283
+
1284
+ #: admin/class-store-overview.php:138
1285
+ msgid "Address"
1286
+ msgstr "Adres"
1287
+
1288
+ #: admin/class-store-overview.php:139
1289
+ msgid "City"
1290
+ msgstr "Stad"
1291
+
1292
+ #: admin/class-store-overview.php:140
1293
+ msgid "State"
1294
+ msgstr "Provincie"
1295
+
1296
+ #: admin/class-store-overview.php:141
1297
+ msgid "Zip"
1298
+ msgstr "Postcode"
1299
+
1300
+ #: admin/class-store-overview.php:142
1301
+ msgid "Status"
1302
+ msgstr "Status"
1303
+
1304
+ #: admin/class-store-overview.php:143
1305
+ msgid "Actions"
1306
+ msgstr "Acties"
1307
+
1308
+ #: admin/class-store-overview.php:172
1309
+ msgid "Activate"
1310
+ msgstr "Activeer"
1311
+
1312
+ #: admin/class-store-overview.php:173
1313
+ msgid "Deactivate"
1314
+ msgstr "Deactiveer"
1315
+
1316
+ #: admin/class-store-overview.php:193
1317
+ msgid "deactivated"
1318
+ msgstr "gedeactiveerd"
1319
+
1320
+ #: admin/class-store-overview.php:194
1321
+ msgid "deactivating"
1322
+ msgstr "gedeactiveerd"
1323
+
1324
+ #: admin/class-store-overview.php:197
1325
+ msgid "activated"
1326
+ msgstr "geactiveerd"
1327
+
1328
+ #: admin/class-store-overview.php:198
1329
+ msgid "activating"
1330
+ msgstr "activeren"
1331
+
1332
+ #: admin/class-store-overview.php:205
1333
+ #, php-format
1334
+ msgid "There was a problem %s the store(s), please try again."
1335
+ msgstr ""
1336
+ "Er is een probleem met het %s van de locatie(s), probeer het nog een keer."
1337
+
1338
+ #: admin/class-store-overview.php:209
1339
+ #, php-format
1340
+ msgid "Store(s) successfully %s."
1341
+ msgstr "Locatie(s) succesvol %s."
1342
+
1343
+ #: admin/class-store-overview.php:230
1344
+ msgid "There was a problem removing the store(s), please try again."
1345
+ msgstr "De locatie(s) konden niet worden verwijderd, probeer het nog een keer."
1346
+
1347
+ #: admin/class-store-overview.php:233
1348
+ msgid "Store(s) successfully removed."
1349
+ msgstr "Locatie(s) succesvol verwijderd."
1350
+
1351
+ #: admin/class-store-overview.php:418
1352
+ msgid "Are you sure you want to delete this store?"
1353
+ msgstr "Weet je zeker dat je deze locatie wilt verwijderen?"
1354
+
1355
+ #: admin/class-store-overview.php:421
1356
+ msgid "Cancel"
1357
+ msgstr "Annuleer"
1358
+
1359
+ #: admin/templates/add-store.php:13 admin/templates/edit-store.php:23
1360
+ msgid "Store details"
1361
+ msgstr "Locatie details"
1362
+
1363
+ #: admin/templates/add-store.php:16 admin/templates/edit-store.php:35
1364
+ msgid "Store Name:"
1365
+ msgstr "Naam:"
1366
+
1367
+ #: admin/templates/add-store.php:20 admin/templates/edit-store.php:39
1368
+ msgid "Address:"
1369
+ msgstr "Adres:"
1370
+
1371
+ #: admin/templates/add-store.php:24 admin/templates/edit-store.php:43
1372
+ msgid "Address 2:"
1373
+ msgstr "Adres 2:"
1374
+
1375
+ #: admin/templates/add-store.php:28 admin/templates/edit-store.php:47
1376
+ msgid "City:"
1377
+ msgstr "Stad:"
1378
+
1379
+ #: admin/templates/add-store.php:32 admin/templates/edit-store.php:51
1380
+ msgid "State / Province:"
1381
+ msgstr "Provincie:"
1382
+
1383
+ #: admin/templates/add-store.php:36 admin/templates/edit-store.php:55
1384
+ msgid "Zip Code:"
1385
+ msgstr "Postcode:"
1386
+
1387
+ #: admin/templates/add-store.php:40 admin/templates/edit-store.php:59
1388
+ msgid "Country:"
1389
+ msgstr "Land:"
1390
+
1391
+ #: admin/templates/add-store.php:45 admin/templates/edit-store.php:64
1392
+ msgid "Latitude:"
1393
+ msgstr "Breedtegraad:"
1394
+
1395
+ #: admin/templates/add-store.php:49 admin/templates/edit-store.php:68
1396
+ msgid "Longitude:"
1397
+ msgstr "Lengtegraad:"
1398
+
1399
+ #: admin/templates/add-store.php:53 admin/templates/edit-store.php:72
1400
+ msgid "Preview location on the map"
1401
+ msgstr "Bekijk voorbeeld op de kaart"
1402
+
1403
+ #: admin/templates/add-store.php:54 admin/templates/edit-store.php:73
1404
+ msgid "You can adjust the location by dragging the marker around"
1405
+ msgstr "Je kan de locatie aanpassen door de marker te verslepen"
1406
+
1407
+ #: admin/templates/add-store.php:65 admin/templates/edit-store.php:84
1408
+ msgid "Extra details"
1409
+ msgstr "Extra informatie"
1410
+
1411
+ #: admin/templates/add-store.php:68 admin/templates/edit-store.php:87
1412
+ #: admin/templates/map-settings.php:277
1413
+ msgid "Phone:"
1414
+ msgstr "Telefoon:"
1415
+
1416
+ #: admin/templates/add-store.php:72 admin/templates/edit-store.php:91
1417
+ #: admin/templates/map-settings.php:281
1418
+ msgid "Fax:"
1419
+ msgstr "Fax:"
1420
+
1421
+ #: admin/templates/add-store.php:76 admin/templates/edit-store.php:95
1422
+ msgid "Email:"
1423
+ msgstr "E-mail:"
1424
+
1425
+ #: admin/templates/add-store.php:80 admin/templates/edit-store.php:99
1426
+ msgid "Url:"
1427
+ msgstr "Url:"
1428
+
1429
+ #: admin/templates/add-store.php:84 admin/templates/edit-store.php:103
1430
+ msgid "Description:"
1431
+ msgstr "Omschrijving:"
1432
+
1433
+ #: admin/templates/add-store.php:88 admin/templates/edit-store.php:107
1434
+ msgid "Operation Hours:"
1435
+ msgstr "Openings- tijden:"
1436
+
1437
+ #: admin/templates/add-store.php:94 admin/templates/edit-store.php:113
1438
+ msgid "Thumbnail:"
1439
+ msgstr "Afbeelding:"
1440
+
1441
+ #: admin/templates/add-store.php:98 admin/templates/edit-store.php:125
1442
+ msgid "Change thumbnail"
1443
+ msgstr "Wijzig afbeelding"
1444
+
1445
+ #: admin/templates/add-store.php:99 admin/templates/edit-store.php:126
1446
+ msgid "Remove"
1447
+ msgstr "Verwijder"
1448
+
1449
+ #: admin/templates/edit-store.php:14
1450
+ msgid "Edit "
1451
+ msgstr "Bewerk "
1452
+
1453
+ #: admin/templates/edit-store.php:26
1454
+ msgid "Status:"
1455
+ msgstr "Status:"
1456
+
1457
+ #: admin/templates/edit-store.php:29
1458
+ msgid "active"
1459
+ msgstr "actief"
1460
+
1461
+ #: admin/templates/edit-store.php:31
1462
+ msgid "inactive"
1463
+ msgstr "niet actief"
1464
+
1465
+ #: admin/templates/edit-store.php:135
1466
+ msgid "Update Store"
1467
+ msgstr "Locatie Bijwerken"
1468
+
1469
+ #: admin/templates/faq.php:6
1470
+ msgid "How do I show the store locator on my page?"
1471
+ msgstr "Hoe plaatst ik de store locator op een pagina?"
1472
+
1473
+ #: admin/templates/faq.php:8
1474
+ msgid ""
1475
+ "Add this shortcode <code>[wpsl]</code> to the page where you want to show "
1476
+ "the store locator."
1477
+ msgstr ""
1478
+ "Voeg deze shortcode <code>[wpsl]</code> toe aan de pagina waar je de store "
1479
+ "locator wil tonen."
1480
+
1481
+ #: admin/templates/faq.php:12
1482
+ msgid ""
1483
+ "The map doesn't display properly. It's either broken in half or doesn't load "
1484
+ "at all."
1485
+ msgstr ""
1486
+ "De kaart is niet goed zichtbaar. Hij wordt niet geladen, of is maar voor de "
1487
+ "helft zichtbaar."
1488
+
1489
+ #: admin/templates/faq.php:14
1490
+ msgid ""
1491
+ "Make sure you have defined a start point for the map under settings -> map "
1492
+ "settings."
1493
+ msgstr ""
1494
+ "Zorg dat er een start locatie is opgegeven op de instellingen pagina -> "
1495
+ "kaart instellingen."
1496
+
1497
+ #: admin/templates/faq.php:18
1498
+ msgid ""
1499
+ "I get an error saying the \"sensor\" parameter specified in the request must "
1500
+ "be set to either \"true\" or \"false\"."
1501
+ msgstr ""
1502
+ "Ik krijg de volgende foutmelding, the \"sensor\" parameter specified in the "
1503
+ "request must be set to either \"true\" or \"false\"."
1504
+
1505
+ #: admin/templates/faq.php:20
1506
+ msgid ""
1507
+ "Make sure you don't have any security plugins, or custom functions running "
1508
+ "that strip away version numbers from file paths."
1509
+ msgstr ""
1510
+ "Zorg ervoor dat je geen beveiligings plugins, of custom functies hebt die "
1511
+ "versie nummers van de bestands paden weghalen."
1512
+
1513
+ #: admin/templates/faq.php:24
1514
+ msgid "The store locator doesn't load, it only shows the number 1?"
1515
+ msgstr "De store locator laadt niet, het toont alleen een '1'?"
1516
+
1517
+ #: admin/templates/faq.php:26
1518
+ msgid ""
1519
+ "This is most likely caused by your theme using ajax navigation ( the loading "
1520
+ "of content without reloading the page ), or a conflict with another plugin. "
1521
+ "Try to disable the ajax navigation in the theme settings, or deactivate the "
1522
+ "plugin that enables it to see if that solves the problem."
1523
+ msgstr ""
1524
+ "Dit wordt waarschijnlijk veroorzaakt doordat je theme ajax navigatie "
1525
+ "gebruikt ( het laden van nieuwe content zonder dat de pagina zelf opnieuw "
1526
+ "geladen wordt ), of door een conflict met een andere plugin. Probeer de ajax "
1527
+ "navigatie in je theme uit te zetten, of deactiveer de plugin die de "
1528
+ "functionaliteit toevoegd om te kijken ofdat dat het probleem oplost."
1529
+
1530
+ #: admin/templates/faq.php:27
1531
+ msgid ""
1532
+ "If you don't use ajax navigation, but do see the number 1 it's probably a "
1533
+ "conflict with another plugin. Try to disable the plugins one by one to see "
1534
+ "if one of them is causing a conflict."
1535
+ msgstr ""
1536
+ "Als je geen ajax navigatie gebruikt, maar wel het getal '1' ziet dan is het "
1537
+ "waarschijnlijk een conflict met een andere plugin. Probeer alle plugins een "
1538
+ "voor een te deactiveren om te kijken welke plugin het probleem veroorzaakt."
1539
+
1540
+ #: admin/templates/faq.php:28
1541
+ #, php-format
1542
+ msgid ""
1543
+ "If you find a plugin or theme that causes a conflict, please report it on "
1544
+ "the <a href=\"%s\">support page</a>."
1545
+ msgstr ""
1546
+ "Als je een plugin of theme tegenkomt dat een probleem veroorzaakt, meld het "
1547
+ "dan op de <a href=\"%s\">support pagina</a>."
1548
+
1549
+ #: admin/templates/faq.php:32
1550
+ msgid "Why does it show the location I searched for in the wrong country?"
1551
+ msgstr "Waarom toont het de locatie waar ik op zocht in het verkeerde land?"
1552
+
1553
+ #: admin/templates/faq.php:34
1554
+ msgid ""
1555
+ "Some location names exist in more then one country, and Google will guess "
1556
+ "which one you mean. This can be fixed by setting the correct \"Map Region\" "
1557
+ "on the settings page -> \"API Settings\"."
1558
+ msgstr ""
1559
+ "Sommige locatie namen komen in meerdere landen voor, en daardoor kan het "
1560
+ "gebeuren dat Google de locatie in het verkeerde land kiest. Dit kan opgelost "
1561
+ "worden door de juiste \"Kaart regio\" in te stellen op de instellingen "
1562
+ "pagina onder \"API Instellingen\"."
1563
+
1564
+ #: admin/templates/map-settings.php:16
1565
+ msgid "API Settings"
1566
+ msgstr "API Instellingen"
1567
+
1568
+ #: admin/templates/map-settings.php:19
1569
+ msgid "API key:"
1570
+ msgstr "API sleutel:"
1571
+
1572
+ #: admin/templates/map-settings.php:20
1573
+ msgid "Optional"
1574
+ msgstr "Optioneel"
1575
+
1576
+ #: admin/templates/map-settings.php:23
1577
+ msgid "Map language:"
1578
+ msgstr "Kaart taal:"
1579
+
1580
+ #: admin/templates/map-settings.php:29
1581
+ msgid "Map region:"
1582
+ msgstr "Kaart regio:"
1583
+
1584
+ #: admin/templates/map-settings.php:34
1585
+ #, php-format
1586
+ msgid ""
1587
+ "* A valid <a href=\"%s\">API key</a> allows you to monitor the API usage "
1588
+ "<br> and is required if you need to purchase additional quota."
1589
+ msgstr ""
1590
+ "* Een geldige <a href=\"%s\">API sleutel</a> maakt het mogelijk om het "
1591
+ "gebruik van de API in de gaten te houden, en is verplicht als je de API "
1592
+ "limiet wil verhogen."
1593
+
1594
+ #: admin/templates/map-settings.php:43
1595
+ msgid "Search Settings"
1596
+ msgstr "Zoek Instellingen"
1597
+
1598
+ #: admin/templates/map-settings.php:46
1599
+ msgid "Distance unit:"
1600
+ msgstr "Afstands eenheid:"
1601
+
1602
+ #: admin/templates/map-settings.php:50
1603
+ msgid "Max search results:"
1604
+ msgstr "Max zoek resultaten:"
1605
+
1606
+ #: admin/templates/map-settings.php:54
1607
+ msgid "Search radius options:"
1608
+ msgstr "Zoek radius opties:"
1609
+
1610
+ #: admin/templates/map-settings.php:58
1611
+ msgid ""
1612
+ "If a user hovers over the search results, the corresponding marker will "
1613
+ "bounce?"
1614
+ msgstr ""
1615
+ "Als een gebruiker over de zoekresultaten beweegt met zijn muis, dan beweegt "
1616
+ "de bijbehorende marker? "
1617
+
1618
+ #: admin/templates/map-settings.php:61
1619
+ msgid "* The default value is set between the ( )"
1620
+ msgstr "* De standaard waarde staat tussen de ( )"
1621
+
1622
+ #: admin/templates/map-settings.php:70
1623
+ msgid "Map Settings"
1624
+ msgstr "Kaart Instellingen"
1625
+
1626
+ #: admin/templates/map-settings.php:73
1627
+ msgid "Attempt to auto-locate the user:"
1628
+ msgstr "Probeer de locatie van de gebruiker automatische te achterhalen:"
1629
+
1630
+ #: admin/templates/map-settings.php:77
1631
+ msgid "Load all stores on page load:"
1632
+ msgstr "Toon all locaties op de kaart zodra de pagina geladen is:"
1633
+
1634
+ #: admin/templates/map-settings.php:81
1635
+ msgid "Start point: *"
1636
+ msgstr "Start locatie: *"
1637
+
1638
+ #: admin/templates/map-settings.php:86
1639
+ msgid "Zoom level:"
1640
+ msgstr "Zoom niveau:"
1641
+
1642
+ #: admin/templates/map-settings.php:90
1643
+ msgid "Map type:"
1644
+ msgstr "Kaart type:"
1645
+
1646
+ #: admin/templates/map-settings.php:94
1647
+ msgid "Show the street view controls?"
1648
+ msgstr "Toon de street view controls?"
1649
+
1650
+ #: admin/templates/map-settings.php:98
1651
+ msgid "Show the pan controls?"
1652
+ msgstr "Toon de pan controls?"
1653
+
1654
+ #: admin/templates/map-settings.php:102
1655
+ msgid "Position of the map controls:"
1656
+ msgstr "Positie van de kaart opties:"
1657
+
1658
+ #: admin/templates/map-settings.php:105
1659
+ msgid "Left"
1660
+ msgstr "links"
1661
+
1662
+ #: admin/templates/map-settings.php:107
1663
+ msgid "Right"
1664
+ msgstr "rechts"
1665
+
1666
+ #: admin/templates/map-settings.php:111
1667
+ msgid "Zoom control style:"
1668
+ msgstr "Zoom control style:"
1669
+
1670
+ #: admin/templates/map-settings.php:114
1671
+ msgid "Small"
1672
+ msgstr "klein"
1673
+
1674
+ #: admin/templates/map-settings.php:116
1675
+ msgid "Large"
1676
+ msgstr "groot"
1677
+
1678
+ #: admin/templates/map-settings.php:119
1679
+ msgid ""
1680
+ "* Required field. If auto-locating the user is disabled or fails, the center "
1681
+ "of the provided city or country will be used as the initial starting point "
1682
+ "for the user."
1683
+ msgstr ""
1684
+ "* Verplicht veld. Als het automatische achterhalen van de gebruikers locatie "
1685
+ "is uitgeschakeld of mislukt, dan wordt het middelpunt van de opgegeven "
1686
+ "locatie als begin punt gebruikt."
1687
+
1688
+ #: admin/templates/map-settings.php:128
1689
+ msgid "Design Settings"
1690
+ msgstr "Design Instellingen"
1691
+
1692
+ #: admin/templates/map-settings.php:131
1693
+ msgid "Store Locator height"
1694
+ msgstr "Store Locator hoogte"
1695
+
1696
+ #: admin/templates/map-settings.php:135
1697
+ msgid "Max width for the infowindow"
1698
+ msgstr "Max breedte voor de infowindow"
1699
+
1700
+ #: admin/templates/map-settings.php:139
1701
+ msgid "Search field width"
1702
+ msgstr "Zoekveld breedte"
1703
+
1704
+ #: admin/templates/map-settings.php:143
1705
+ msgid "Search and radius label width *"
1706
+ msgstr "Zoek en radius label breedte *"
1707
+
1708
+ #: admin/templates/map-settings.php:147
1709
+ msgid "Select template"
1710
+ msgstr "Selecteer template"
1711
+
1712
+ #: admin/templates/map-settings.php:151
1713
+ msgid "Hide the scrollbar?"
1714
+ msgstr "Verberg de scrollbar?"
1715
+
1716
+ #: admin/templates/map-settings.php:155
1717
+ msgid "Show the limit results dropdown?"
1718
+ msgstr "Toon de limiteer resultaten dropdown?"
1719
+
1720
+ #: admin/templates/map-settings.php:159
1721
+ msgid "Open links in a new window?"
1722
+ msgstr "Open links in een nieuw venster?"
1723
+
1724
+ #: admin/templates/map-settings.php:163
1725
+ msgid "Show a reset map button?"
1726
+ msgstr "Toon een knop om de kaart te resetten?"
1727
+
1728
+ #: admin/templates/map-settings.php:167
1729
+ msgid ""
1730
+ "When a user clicks on \"Directions\", open a new window and show the route "
1731
+ "on maps.google.com"
1732
+ msgstr ""
1733
+ "Zodra een gebruiker op \"Route\" klikt, open een nieuwe venster en toon de "
1734
+ "route op maps.google.com"
1735
+
1736
+ #: admin/templates/map-settings.php:171
1737
+ msgid "Show a \"More info\" link in the store listings?"
1738
+ msgstr "Toon een \"Meer info\" link in de locatie lijst?"
1739
+
1740
+ #: admin/templates/map-settings.php:175
1741
+ msgid "Where do you want to show the \"More info\" details?"
1742
+ msgstr "Waar wil je de \"Meer info\" details tonen?"
1743
+
1744
+ #: admin/templates/map-settings.php:179
1745
+ msgid "If a store url exists, make the store name clickable?"
1746
+ msgstr "Als een locatie url bestaat, maak de locatie naam dan klikbaar?"
1747
+
1748
+ #: admin/templates/map-settings.php:183
1749
+ msgid "Make the phone number clickable on mobile devices?"
1750
+ msgstr "Maak het telefoonnummer klikbaar op mobiele apparaten?"
1751
+
1752
+ #: admin/templates/map-settings.php:187
1753
+ msgid ""
1754
+ "If available for the current location, show a link to enable street view "
1755
+ "from the infowindow?"
1756
+ msgstr ""
1757
+ "Als voor de huidge locatie street view beschikbaar is, toon dan een link om "
1758
+ "het vanuit de infowindow te activeren?"
1759
+
1760
+ #: admin/templates/map-settings.php:191
1761
+ msgid "Show a \"zoom to\" link in the infowindow?"
1762
+ msgstr "Toon een \"zoom hier\" link in de infowindow?"
1763
+
1764
+ #: admin/templates/map-settings.php:195
1765
+ msgid "On pageload move the mousecursor to the input field. **"
1766
+ msgstr ""
1767
+ "Als de pagina wordt geladen, verplaats de muiscursor dan naar het invul "
1768
+ "veld. **"
1769
+
1770
+ #: admin/templates/map-settings.php:198
1771
+ msgid ""
1772
+ "* This is the text that is placed before the search input and radius dropdown"
1773
+ msgstr ""
1774
+ "* Dit is de tekst die voor het zoekveld en radius dropdown geplaatst wordt."
1775
+
1776
+ #: admin/templates/map-settings.php:199
1777
+ msgid ""
1778
+ "** If the store locator is not placed at the top of the page, enabling this "
1779
+ "feature can result in the page sliding down."
1780
+ msgstr ""
1781
+ "** Als de store locator niet bovenaan de pagina geplaatst wordt, dan kan "
1782
+ "deze instelling ervoor zorgen dat de pagina naar benenden schuift tijden het "
1783
+ "laden."
1784
+
1785
+ #: admin/templates/map-settings.php:208
1786
+ msgid "Markers"
1787
+ msgstr "Markers"
1788
+
1789
+ #: admin/templates/map-settings.php:212
1790
+ msgid "Enable marker clusters? *"
1791
+ msgstr "Activeer marker clusters? *"
1792
+
1793
+ #: admin/templates/map-settings.php:216
1794
+ msgid "Max zoom level:"
1795
+ msgstr "Max zoom niveau:"
1796
+
1797
+ #: admin/templates/map-settings.php:220
1798
+ msgid "Cluster size:"
1799
+ msgstr "Cluster grote:"
1800
+
1801
+ #: admin/templates/map-settings.php:223
1802
+ msgid "* Recommended for maps with a large amounts of markers."
1803
+ msgstr "* Aan te raden voor kaarten met grote hoeveelheden markers."
1804
+
1805
+ #: admin/templates/map-settings.php:232
1806
+ msgid "Store Editor Settings"
1807
+ msgstr "Locatie Editor Instellingen"
1808
+
1809
+ #: admin/templates/map-settings.php:235
1810
+ msgid "Default country that will be used on the \"Add Store\" page."
1811
+ msgstr ""
1812
+ "Het land dat standaard gebruikt wordt op de \"Locatie Toevoegen\" pagina."
1813
+
1814
+ #: admin/templates/map-settings.php:246
1815
+ msgid "Labels"
1816
+ msgstr "Labels"
1817
+
1818
+ #: admin/templates/map-settings.php:249
1819
+ msgid "Your location:"
1820
+ msgstr "Uw locatie:"
1821
+
1822
+ #: admin/templates/map-settings.php:253
1823
+ msgid "Search radius:"
1824
+ msgstr "Zoek radius:"
1825
+
1826
+ #: admin/templates/map-settings.php:257
1827
+ msgid "No results found:"
1828
+ msgstr "Geen locaties gevonden:"
1829
+
1830
+ #: admin/templates/map-settings.php:261
1831
+ msgid "Search:"
1832
+ msgstr "Zoek:"
1833
+
1834
+ #: admin/templates/map-settings.php:265
1835
+ msgid "Searching (preloader text):"
1836
+ msgstr "Aan het zoeken (preloader tekst):"
1837
+
1838
+ #: admin/templates/map-settings.php:269
1839
+ msgid "Results:"
1840
+ msgstr "Resultaten:"
1841
+
1842
+ #: admin/templates/map-settings.php:273
1843
+ msgid "More info:"
1844
+ msgstr "Meer info:"
1845
+
1846
+ #: admin/templates/map-settings.php:285
1847
+ msgid "Hours:"
1848
+ msgstr "Openingstijden:"
1849
+
1850
+ #: admin/templates/map-settings.php:289
1851
+ msgid "Start location:"
1852
+ msgstr "Start locatie:"
1853
+
1854
+ #: admin/templates/map-settings.php:293
1855
+ msgid "Get directions:"
1856
+ msgstr "Toon route:"
1857
+
1858
+ #: admin/templates/map-settings.php:297
1859
+ msgid "No directions found:"
1860
+ msgstr "Geen route gevonden:"
1861
+
1862
+ #: admin/templates/map-settings.php:301
1863
+ msgid "Back:"
1864
+ msgstr "Terug:"
1865
+
1866
+ #: admin/templates/map-settings.php:305
1867
+ msgid "Reset:"
1868
+ msgstr "Herstel:"
1869
+
1870
+ #: admin/templates/map-settings.php:309
1871
+ msgid "Street view:"
1872
+ msgstr "Street view:"
1873
+
1874
+ #: admin/templates/map-settings.php:313
1875
+ msgid "Zoom here:"
1876
+ msgstr "Zoom hier:"
1877
+
1878
+ #: admin/templates/map-settings.php:317
1879
+ msgid "General error:"
1880
+ msgstr "Foutmelding:"
1881
+
1882
+ #: admin/templates/map-settings.php:321
1883
+ msgid "Query limit error:"
1884
+ msgstr "Query limit foutmelding:"
1885
+
1886
+ #: admin/templates/map-settings.php:324
1887
+ #, php-format
1888
+ msgid ""
1889
+ "* You can raise the <a href=\"%s\">usage limit</a> by obtaining an API <a "
1890
+ "href=\"%s\">key</a>, <br> and fill in the \"API key\" field at the top of "
1891
+ "this page."
1892
+ msgstr ""
1893
+ "* Je kan de <a href=\"%s\">gebruiks limiet</a> verhogen door een API <a href="
1894
+ "\"%s\">sleutel</a> aan te vragen, <br> en die in het \"API sleutel\" veld "
1895
+ "bovenaan de pagina in te vullen."
1896
+
1897
+ #: admin/templates/map-settings.php:330
1898
+ msgid "Update Settings"
1899
+ msgstr "Instellingen Bijwerken"
1900
+
1901
+ #: wp-store-locator.php:261
1902
+ msgid "Start location"
1903
+ msgstr "Start locatie"
1904
+
1905
+ #: wp-store-locator.php:262
1906
+ msgid "Your location"
1907
+ msgstr "Uw locatie"
1908
+
1909
+ #: wp-store-locator.php:263
1910
+ msgid "Search"
1911
+ msgstr "Zoek"
1912
+
1913
+ #: wp-store-locator.php:264
1914
+ msgid "Searching..."
1915
+ msgstr "Zoeken..."
1916
+
1917
+ #: wp-store-locator.php:265
1918
+ msgid "Search radius"
1919
+ msgstr "Zoek radius"
1920
+
1921
+ #: wp-store-locator.php:266
1922
+ msgid "No results found"
1923
+ msgstr "Geen locaties gevonden"
1924
+
1925
+ #: wp-store-locator.php:267
1926
+ msgid "Results"
1927
+ msgstr "Resultaten"
1928
+
1929
+ #: wp-store-locator.php:269
1930
+ msgid "Directions"
1931
+ msgstr "Toon route"
1932
+
1933
+ #: wp-store-locator.php:275
1934
+ msgid "Something went wrong, please try again!"
1935
+ msgstr "Er ging iets fout, probeer het nog een keer!"
1936
+
1937
+ #: wp-store-locator.php:276
1938
+ msgid "API usage limit reached"
1939
+ msgstr "API gebruikslimiet bereikt"
1940
+
1941
+ #: wp-store-locator.php:277
1942
+ msgid "Phone"
1943
+ msgstr "Telefoon"
1944
+
1945
+ #: wp-store-locator.php:278
1946
+ msgid "Fax"
1947
+ msgstr "Fax"
1948
+
1949
+ #: wp-store-locator.php:279
1950
+ msgid "Hours"
1951
+ msgstr "Openingstijden"
1952
+
1953
+ #: wp-store-locator.php:317
1954
+ msgid "Show the store list below the map"
1955
+ msgstr "Toon the locatie lijst onder de kaart"
languages/wpsl.pot ADDED
@@ -0,0 +1,1798 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: WP Store Locator v1.2.20\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2014-05-08 16:51+0100\n"
6
+ "PO-Revision-Date: 2014-05-08 17:17+0100\n"
7
+ "Last-Translator: \n"
8
+ "Language-Team: \n"
9
+ "Language: en_US\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
+ "X-Generator: Poedit 1.6.5\n"
15
+ "X-Poedit-SourceCharset: utf-8\n"
16
+ "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
17
+ "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
18
+ "X-Poedit-Basepath: ../\n"
19
+ "X-Textdomain-Support: yes\n"
20
+ "X-Poedit-SearchPath-0: .\n"
21
+
22
+ #: admin/class-admin.php:235
23
+ msgid "Store Locator"
24
+ msgstr ""
25
+
26
+ #: admin/class-admin.php:236
27
+ msgid "Manage Stores"
28
+ msgstr ""
29
+
30
+ #: admin/class-admin.php:237 admin/class-admin.php:559
31
+ #: admin/templates/add-store.php:107
32
+ msgid "Add Store"
33
+ msgstr ""
34
+
35
+ #: admin/class-admin.php:238 admin/class-admin.php:560
36
+ #: admin/templates/map-settings.php:2
37
+ msgid "Settings"
38
+ msgstr ""
39
+
40
+ #: admin/class-admin.php:239 admin/templates/faq.php:2
41
+ msgid "FAQ"
42
+ msgstr ""
43
+
44
+ #: admin/class-admin.php:255 admin/class-store-overview.php:31
45
+ msgid "Stores"
46
+ msgstr ""
47
+
48
+ #: admin/class-admin.php:424
49
+ msgid "There was a problem updating the store details, please try again."
50
+ msgstr ""
51
+
52
+ #: admin/class-admin.php:428
53
+ msgid "Store details updated."
54
+ msgstr ""
55
+
56
+ #: admin/class-admin.php:474
57
+ msgid "There was a problem saving the new store details, please try again."
58
+ msgstr ""
59
+
60
+ #: admin/class-admin.php:478
61
+ msgid "Store succesfully added."
62
+ msgstr ""
63
+
64
+ #: admin/class-admin.php:506
65
+ msgid "Please fill in all the required fields."
66
+ msgstr ""
67
+
68
+ #: admin/class-admin.php:558
69
+ msgid "Current Stores"
70
+ msgstr ""
71
+
72
+ #: admin/class-admin.php:595
73
+ msgid ""
74
+ "The max results field cannot be empty, the default value has been restored."
75
+ msgstr ""
76
+
77
+ #: admin/class-admin.php:598
78
+ msgid ""
79
+ "The search radius field cannot be empty, the default value has been restored."
80
+ msgstr ""
81
+
82
+ #: admin/class-admin.php:601
83
+ msgid ""
84
+ "One of the label fields was left empty, the default value for that field has "
85
+ "been restored."
86
+ msgstr ""
87
+
88
+ #: admin/class-admin.php:604
89
+ msgid ""
90
+ "Please provide the name of a city or country that can be used as a starting "
91
+ "point under \"Map Settings\". This will only be used if auto-locating the "
92
+ "user fails, or the option itself is disabled."
93
+ msgstr ""
94
+
95
+ #: admin/class-admin.php:619
96
+ #, php-format
97
+ msgid ""
98
+ "Before adding the [wpsl] shortcode to a page, please don't forget to define "
99
+ "a start point on the %ssettings%s page."
100
+ msgstr ""
101
+
102
+ #: admin/class-admin.php:619
103
+ msgid "Dismiss"
104
+ msgstr ""
105
+
106
+ #: admin/class-admin.php:870
107
+ msgid ""
108
+ "The Google Geocoding API returned no results for the store location. Please "
109
+ "change the location and try again."
110
+ msgstr ""
111
+
112
+ #: admin/class-admin.php:873
113
+ #, php-format
114
+ msgid ""
115
+ "You have reached the daily allowed geocoding limit, you can read more <a "
116
+ "href=\"%s\">here</a>."
117
+ msgstr ""
118
+
119
+ #: admin/class-admin.php:876
120
+ msgid ""
121
+ "The Google Geocoding API failed to return valid data, please try again later."
122
+ msgstr ""
123
+
124
+ #: admin/class-admin.php:956
125
+ msgid "Start location marker:"
126
+ msgstr ""
127
+
128
+ #: admin/class-admin.php:958
129
+ msgid "Store location marker:"
130
+ msgstr ""
131
+
132
+ #: admin/class-admin.php:1118 wp-store-locator.php:294
133
+ msgid "Default"
134
+ msgstr ""
135
+
136
+ #: admin/class-admin.php:1226
137
+ msgid "In the store listings"
138
+ msgstr ""
139
+
140
+ #: admin/class-admin.php:1227
141
+ msgid "In the info window on the map"
142
+ msgstr ""
143
+
144
+ #: admin/class-admin.php:1253
145
+ msgid "Select your language"
146
+ msgstr ""
147
+
148
+ #: admin/class-admin.php:1254
149
+ msgid "English"
150
+ msgstr ""
151
+
152
+ #: admin/class-admin.php:1255
153
+ msgid "Arabic"
154
+ msgstr ""
155
+
156
+ #: admin/class-admin.php:1256
157
+ msgid "Basque"
158
+ msgstr ""
159
+
160
+ #: admin/class-admin.php:1257
161
+ msgid "Bulgarian"
162
+ msgstr ""
163
+
164
+ #: admin/class-admin.php:1258
165
+ msgid "Bengali"
166
+ msgstr ""
167
+
168
+ #: admin/class-admin.php:1259
169
+ msgid "Catalan"
170
+ msgstr ""
171
+
172
+ #: admin/class-admin.php:1260
173
+ msgid "Czech"
174
+ msgstr ""
175
+
176
+ #: admin/class-admin.php:1261
177
+ msgid "Danish"
178
+ msgstr ""
179
+
180
+ #: admin/class-admin.php:1262
181
+ msgid "German"
182
+ msgstr ""
183
+
184
+ #: admin/class-admin.php:1263
185
+ msgid "Greek"
186
+ msgstr ""
187
+
188
+ #: admin/class-admin.php:1264
189
+ msgid "English (Australian)"
190
+ msgstr ""
191
+
192
+ #: admin/class-admin.php:1265
193
+ msgid "English (Great Britain)"
194
+ msgstr ""
195
+
196
+ #: admin/class-admin.php:1266
197
+ msgid "Spanish"
198
+ msgstr ""
199
+
200
+ #: admin/class-admin.php:1267
201
+ msgid "Farsi"
202
+ msgstr ""
203
+
204
+ #: admin/class-admin.php:1268
205
+ msgid "Finnish"
206
+ msgstr ""
207
+
208
+ #: admin/class-admin.php:1269
209
+ msgid "Filipino"
210
+ msgstr ""
211
+
212
+ #: admin/class-admin.php:1270
213
+ msgid "French"
214
+ msgstr ""
215
+
216
+ #: admin/class-admin.php:1271
217
+ msgid "Galician"
218
+ msgstr ""
219
+
220
+ #: admin/class-admin.php:1272
221
+ msgid "Gujarati"
222
+ msgstr ""
223
+
224
+ #: admin/class-admin.php:1273
225
+ msgid "Hindi"
226
+ msgstr ""
227
+
228
+ #: admin/class-admin.php:1274
229
+ msgid "Croatian"
230
+ msgstr ""
231
+
232
+ #: admin/class-admin.php:1275
233
+ msgid "Hungarian"
234
+ msgstr ""
235
+
236
+ #: admin/class-admin.php:1276
237
+ msgid "Indonesian"
238
+ msgstr ""
239
+
240
+ #: admin/class-admin.php:1277
241
+ msgid "Italian"
242
+ msgstr ""
243
+
244
+ #: admin/class-admin.php:1278
245
+ msgid "Hebrew"
246
+ msgstr ""
247
+
248
+ #: admin/class-admin.php:1279
249
+ msgid "Japanese"
250
+ msgstr ""
251
+
252
+ #: admin/class-admin.php:1280
253
+ msgid "Kannada"
254
+ msgstr ""
255
+
256
+ #: admin/class-admin.php:1281
257
+ msgid "Korean"
258
+ msgstr ""
259
+
260
+ #: admin/class-admin.php:1282
261
+ msgid "Lithuanian"
262
+ msgstr ""
263
+
264
+ #: admin/class-admin.php:1283
265
+ msgid "Latvian"
266
+ msgstr ""
267
+
268
+ #: admin/class-admin.php:1284
269
+ msgid "Malayalam"
270
+ msgstr ""
271
+
272
+ #: admin/class-admin.php:1285
273
+ msgid "Marathi"
274
+ msgstr ""
275
+
276
+ #: admin/class-admin.php:1286
277
+ msgid "Dutch"
278
+ msgstr ""
279
+
280
+ #: admin/class-admin.php:1287
281
+ msgid "Norwegian"
282
+ msgstr ""
283
+
284
+ #: admin/class-admin.php:1288
285
+ msgid "Norwegian Nynorsk"
286
+ msgstr ""
287
+
288
+ #: admin/class-admin.php:1289
289
+ msgid "Polish"
290
+ msgstr ""
291
+
292
+ #: admin/class-admin.php:1290
293
+ msgid "Portuguese"
294
+ msgstr ""
295
+
296
+ #: admin/class-admin.php:1291
297
+ msgid "Portuguese (Brazil)"
298
+ msgstr ""
299
+
300
+ #: admin/class-admin.php:1292
301
+ msgid "Portuguese (Portugal)"
302
+ msgstr ""
303
+
304
+ #: admin/class-admin.php:1293
305
+ msgid "Romanian"
306
+ msgstr ""
307
+
308
+ #: admin/class-admin.php:1294
309
+ msgid "Russian"
310
+ msgstr ""
311
+
312
+ #: admin/class-admin.php:1295
313
+ msgid "Slovak"
314
+ msgstr ""
315
+
316
+ #: admin/class-admin.php:1296
317
+ msgid "Slovenian"
318
+ msgstr ""
319
+
320
+ #: admin/class-admin.php:1297
321
+ msgid "Serbian"
322
+ msgstr ""
323
+
324
+ #: admin/class-admin.php:1298
325
+ msgid "Swedish"
326
+ msgstr ""
327
+
328
+ #: admin/class-admin.php:1299
329
+ msgid "Tagalog"
330
+ msgstr ""
331
+
332
+ #: admin/class-admin.php:1300
333
+ msgid "Tamil"
334
+ msgstr ""
335
+
336
+ #: admin/class-admin.php:1301
337
+ msgid "Telugu"
338
+ msgstr ""
339
+
340
+ #: admin/class-admin.php:1302
341
+ msgid "Thai"
342
+ msgstr ""
343
+
344
+ #: admin/class-admin.php:1303
345
+ msgid "Turkish"
346
+ msgstr ""
347
+
348
+ #: admin/class-admin.php:1304
349
+ msgid "Ukrainian"
350
+ msgstr ""
351
+
352
+ #: admin/class-admin.php:1305
353
+ msgid "Vietnamese"
354
+ msgstr ""
355
+
356
+ #: admin/class-admin.php:1306
357
+ msgid "Chinese (Simplified)"
358
+ msgstr ""
359
+
360
+ #: admin/class-admin.php:1307
361
+ msgid "Chinese (Traditional)"
362
+ msgstr ""
363
+
364
+ #: admin/class-admin.php:1312
365
+ msgid "Select your region"
366
+ msgstr ""
367
+
368
+ #: admin/class-admin.php:1313
369
+ msgid "Afghanistan"
370
+ msgstr ""
371
+
372
+ #: admin/class-admin.php:1314
373
+ msgid "Albania"
374
+ msgstr ""
375
+
376
+ #: admin/class-admin.php:1315
377
+ msgid "Algeria"
378
+ msgstr ""
379
+
380
+ #: admin/class-admin.php:1316
381
+ msgid "American Samoa"
382
+ msgstr ""
383
+
384
+ #: admin/class-admin.php:1317
385
+ msgid "Andorra"
386
+ msgstr ""
387
+
388
+ #: admin/class-admin.php:1318
389
+ msgid "Anguilla"
390
+ msgstr ""
391
+
392
+ #: admin/class-admin.php:1319
393
+ msgid "Angola"
394
+ msgstr ""
395
+
396
+ #: admin/class-admin.php:1320
397
+ msgid "Antigua and Barbuda"
398
+ msgstr ""
399
+
400
+ #: admin/class-admin.php:1321
401
+ msgid "Argentina"
402
+ msgstr ""
403
+
404
+ #: admin/class-admin.php:1322
405
+ msgid "Armenia"
406
+ msgstr ""
407
+
408
+ #: admin/class-admin.php:1323
409
+ msgid "Aruba"
410
+ msgstr ""
411
+
412
+ #: admin/class-admin.php:1324
413
+ msgid "Australia"
414
+ msgstr ""
415
+
416
+ #: admin/class-admin.php:1325
417
+ msgid "Austria"
418
+ msgstr ""
419
+
420
+ #: admin/class-admin.php:1326
421
+ msgid "Azerbaijan"
422
+ msgstr ""
423
+
424
+ #: admin/class-admin.php:1327
425
+ msgid "Bahamas"
426
+ msgstr ""
427
+
428
+ #: admin/class-admin.php:1328
429
+ msgid "Bahrain"
430
+ msgstr ""
431
+
432
+ #: admin/class-admin.php:1329
433
+ msgid "Bangladesh"
434
+ msgstr ""
435
+
436
+ #: admin/class-admin.php:1330
437
+ msgid "Barbados"
438
+ msgstr ""
439
+
440
+ #: admin/class-admin.php:1331
441
+ msgid "Belarus"
442
+ msgstr ""
443
+
444
+ #: admin/class-admin.php:1332
445
+ msgid "Belgium"
446
+ msgstr ""
447
+
448
+ #: admin/class-admin.php:1333
449
+ msgid "Belize"
450
+ msgstr ""
451
+
452
+ #: admin/class-admin.php:1334
453
+ msgid "Benin"
454
+ msgstr ""
455
+
456
+ #: admin/class-admin.php:1335
457
+ msgid "Bermuda"
458
+ msgstr ""
459
+
460
+ #: admin/class-admin.php:1336
461
+ msgid "Bhutan"
462
+ msgstr ""
463
+
464
+ #: admin/class-admin.php:1337
465
+ msgid "Bolivia"
466
+ msgstr ""
467
+
468
+ #: admin/class-admin.php:1338
469
+ msgid "Bosnia and Herzegovina"
470
+ msgstr ""
471
+
472
+ #: admin/class-admin.php:1339
473
+ msgid "Botswana"
474
+ msgstr ""
475
+
476
+ #: admin/class-admin.php:1340
477
+ msgid "Brazil"
478
+ msgstr ""
479
+
480
+ #: admin/class-admin.php:1341
481
+ msgid "British Indian Ocean Territory"
482
+ msgstr ""
483
+
484
+ #: admin/class-admin.php:1342
485
+ msgid "Brunei"
486
+ msgstr ""
487
+
488
+ #: admin/class-admin.php:1343
489
+ msgid "Bulgaria"
490
+ msgstr ""
491
+
492
+ #: admin/class-admin.php:1344
493
+ msgid "Burkina Faso"
494
+ msgstr ""
495
+
496
+ #: admin/class-admin.php:1345
497
+ msgid "Burundi"
498
+ msgstr ""
499
+
500
+ #: admin/class-admin.php:1346
501
+ msgid "Cambodia"
502
+ msgstr ""
503
+
504
+ #: admin/class-admin.php:1347
505
+ msgid "Cameroon"
506
+ msgstr ""
507
+
508
+ #: admin/class-admin.php:1348
509
+ msgid "Canada"
510
+ msgstr ""
511
+
512
+ #: admin/class-admin.php:1349
513
+ msgid "Cape Verde"
514
+ msgstr ""
515
+
516
+ #: admin/class-admin.php:1350
517
+ msgid "Cayman Islands"
518
+ msgstr ""
519
+
520
+ #: admin/class-admin.php:1351
521
+ msgid "Central African Republic"
522
+ msgstr ""
523
+
524
+ #: admin/class-admin.php:1352
525
+ msgid "Chad"
526
+ msgstr ""
527
+
528
+ #: admin/class-admin.php:1353
529
+ msgid "Chile"
530
+ msgstr ""
531
+
532
+ #: admin/class-admin.php:1354
533
+ msgid "China"
534
+ msgstr ""
535
+
536
+ #: admin/class-admin.php:1355
537
+ msgid "Christmas Island"
538
+ msgstr ""
539
+
540
+ #: admin/class-admin.php:1356
541
+ msgid "Cocos Islands"
542
+ msgstr ""
543
+
544
+ #: admin/class-admin.php:1357
545
+ msgid "Colombia"
546
+ msgstr ""
547
+
548
+ #: admin/class-admin.php:1358
549
+ msgid "Comoros"
550
+ msgstr ""
551
+
552
+ #: admin/class-admin.php:1359
553
+ msgid "Congo"
554
+ msgstr ""
555
+
556
+ #: admin/class-admin.php:1360
557
+ msgid "Costa Rica"
558
+ msgstr ""
559
+
560
+ #: admin/class-admin.php:1361
561
+ msgid "Côte d'Ivoire"
562
+ msgstr ""
563
+
564
+ #: admin/class-admin.php:1362
565
+ msgid "Croatia"
566
+ msgstr ""
567
+
568
+ #: admin/class-admin.php:1363
569
+ msgid "Cuba"
570
+ msgstr ""
571
+
572
+ #: admin/class-admin.php:1364
573
+ msgid "Czech Republic"
574
+ msgstr ""
575
+
576
+ #: admin/class-admin.php:1365
577
+ msgid "Denmark"
578
+ msgstr ""
579
+
580
+ #: admin/class-admin.php:1366
581
+ msgid "Djibouti"
582
+ msgstr ""
583
+
584
+ #: admin/class-admin.php:1367
585
+ msgid "Democratic Republic of the Congo"
586
+ msgstr ""
587
+
588
+ #: admin/class-admin.php:1368
589
+ msgid "Dominica"
590
+ msgstr ""
591
+
592
+ #: admin/class-admin.php:1369
593
+ msgid "Dominican Republic"
594
+ msgstr ""
595
+
596
+ #: admin/class-admin.php:1370
597
+ msgid "Ecuador"
598
+ msgstr ""
599
+
600
+ #: admin/class-admin.php:1371
601
+ msgid "Egypt"
602
+ msgstr ""
603
+
604
+ #: admin/class-admin.php:1372
605
+ msgid "El Salvador"
606
+ msgstr ""
607
+
608
+ #: admin/class-admin.php:1373
609
+ msgid "Equatorial Guinea"
610
+ msgstr ""
611
+
612
+ #: admin/class-admin.php:1374
613
+ msgid "Eritrea"
614
+ msgstr ""
615
+
616
+ #: admin/class-admin.php:1375
617
+ msgid "Estonia"
618
+ msgstr ""
619
+
620
+ #: admin/class-admin.php:1376
621
+ msgid "Ethiopia"
622
+ msgstr ""
623
+
624
+ #: admin/class-admin.php:1377
625
+ msgid "Fiji"
626
+ msgstr ""
627
+
628
+ #: admin/class-admin.php:1378
629
+ msgid "Finland"
630
+ msgstr ""
631
+
632
+ #: admin/class-admin.php:1379
633
+ msgid "France"
634
+ msgstr ""
635
+
636
+ #: admin/class-admin.php:1380
637
+ msgid "French Guiana"
638
+ msgstr ""
639
+
640
+ #: admin/class-admin.php:1381
641
+ msgid "Gabon"
642
+ msgstr ""
643
+
644
+ #: admin/class-admin.php:1382
645
+ msgid "Gambia"
646
+ msgstr ""
647
+
648
+ #: admin/class-admin.php:1383
649
+ msgid "Germany"
650
+ msgstr ""
651
+
652
+ #: admin/class-admin.php:1384
653
+ msgid "Ghana"
654
+ msgstr ""
655
+
656
+ #: admin/class-admin.php:1385
657
+ msgid "Greenland"
658
+ msgstr ""
659
+
660
+ #: admin/class-admin.php:1386
661
+ msgid "Greece"
662
+ msgstr ""
663
+
664
+ #: admin/class-admin.php:1387
665
+ msgid "Grenada"
666
+ msgstr ""
667
+
668
+ #: admin/class-admin.php:1388
669
+ msgid "Guam"
670
+ msgstr ""
671
+
672
+ #: admin/class-admin.php:1389
673
+ msgid "Guadeloupe"
674
+ msgstr ""
675
+
676
+ #: admin/class-admin.php:1390
677
+ msgid "Guatemala"
678
+ msgstr ""
679
+
680
+ #: admin/class-admin.php:1391
681
+ msgid "Guinea"
682
+ msgstr ""
683
+
684
+ #: admin/class-admin.php:1392
685
+ msgid "Guinea-Bissau"
686
+ msgstr ""
687
+
688
+ #: admin/class-admin.php:1393
689
+ msgid "Haiti"
690
+ msgstr ""
691
+
692
+ #: admin/class-admin.php:1394
693
+ msgid "Honduras"
694
+ msgstr ""
695
+
696
+ #: admin/class-admin.php:1395
697
+ msgid "Hong Kong"
698
+ msgstr ""
699
+
700
+ #: admin/class-admin.php:1396
701
+ msgid "Hungary"
702
+ msgstr ""
703
+
704
+ #: admin/class-admin.php:1397
705
+ msgid "Iceland"
706
+ msgstr ""
707
+
708
+ #: admin/class-admin.php:1398
709
+ msgid "India"
710
+ msgstr ""
711
+
712
+ #: admin/class-admin.php:1399
713
+ msgid "Indonesia"
714
+ msgstr ""
715
+
716
+ #: admin/class-admin.php:1400
717
+ msgid "Iran"
718
+ msgstr ""
719
+
720
+ #: admin/class-admin.php:1401
721
+ msgid "Iraq"
722
+ msgstr ""
723
+
724
+ #: admin/class-admin.php:1402
725
+ msgid "Ireland"
726
+ msgstr ""
727
+
728
+ #: admin/class-admin.php:1403
729
+ msgid "Israel"
730
+ msgstr ""
731
+
732
+ #: admin/class-admin.php:1404
733
+ msgid "Italy"
734
+ msgstr ""
735
+
736
+ #: admin/class-admin.php:1405
737
+ msgid "Jamaica"
738
+ msgstr ""
739
+
740
+ #: admin/class-admin.php:1406
741
+ msgid "Japan"
742
+ msgstr ""
743
+
744
+ #: admin/class-admin.php:1407
745
+ msgid "Jordan"
746
+ msgstr ""
747
+
748
+ #: admin/class-admin.php:1408
749
+ msgid "Kazakhstan"
750
+ msgstr ""
751
+
752
+ #: admin/class-admin.php:1409
753
+ msgid "Kenya"
754
+ msgstr ""
755
+
756
+ #: admin/class-admin.php:1410
757
+ msgid "Kuwait"
758
+ msgstr ""
759
+
760
+ #: admin/class-admin.php:1411
761
+ msgid "Kyrgyzstan"
762
+ msgstr ""
763
+
764
+ #: admin/class-admin.php:1412
765
+ msgid "Laos"
766
+ msgstr ""
767
+
768
+ #: admin/class-admin.php:1413
769
+ msgid "Latvia"
770
+ msgstr ""
771
+
772
+ #: admin/class-admin.php:1414
773
+ msgid "Lebanon"
774
+ msgstr ""
775
+
776
+ #: admin/class-admin.php:1415
777
+ msgid "Lesotho"
778
+ msgstr ""
779
+
780
+ #: admin/class-admin.php:1416
781
+ msgid "Liberia"
782
+ msgstr ""
783
+
784
+ #: admin/class-admin.php:1417
785
+ msgid "Libya"
786
+ msgstr ""
787
+
788
+ #: admin/class-admin.php:1418
789
+ msgid "Liechtenstein"
790
+ msgstr ""
791
+
792
+ #: admin/class-admin.php:1419
793
+ msgid "Lithuania"
794
+ msgstr ""
795
+
796
+ #: admin/class-admin.php:1420
797
+ msgid "Luxembourg"
798
+ msgstr ""
799
+
800
+ #: admin/class-admin.php:1421
801
+ msgid "Macau"
802
+ msgstr ""
803
+
804
+ #: admin/class-admin.php:1422
805
+ msgid "Macedonia"
806
+ msgstr ""
807
+
808
+ #: admin/class-admin.php:1423
809
+ msgid "Madagascar"
810
+ msgstr ""
811
+
812
+ #: admin/class-admin.php:1424
813
+ msgid "Malawi"
814
+ msgstr ""
815
+
816
+ #: admin/class-admin.php:1425
817
+ msgid "Malaysia "
818
+ msgstr ""
819
+
820
+ #: admin/class-admin.php:1426
821
+ msgid "Mali"
822
+ msgstr ""
823
+
824
+ #: admin/class-admin.php:1427
825
+ msgid "Marshall Islands"
826
+ msgstr ""
827
+
828
+ #: admin/class-admin.php:1428
829
+ msgid "Martinique"
830
+ msgstr ""
831
+
832
+ #: admin/class-admin.php:1429
833
+ msgid "Mauritania"
834
+ msgstr ""
835
+
836
+ #: admin/class-admin.php:1430
837
+ msgid "Mauritius"
838
+ msgstr ""
839
+
840
+ #: admin/class-admin.php:1431
841
+ msgid "Mexico"
842
+ msgstr ""
843
+
844
+ #: admin/class-admin.php:1432
845
+ msgid "Micronesia"
846
+ msgstr ""
847
+
848
+ #: admin/class-admin.php:1433
849
+ msgid "Moldova"
850
+ msgstr ""
851
+
852
+ #: admin/class-admin.php:1434
853
+ msgid "Monaco"
854
+ msgstr ""
855
+
856
+ #: admin/class-admin.php:1435
857
+ msgid "Mongolia"
858
+ msgstr ""
859
+
860
+ #: admin/class-admin.php:1436
861
+ msgid "Montenegro"
862
+ msgstr ""
863
+
864
+ #: admin/class-admin.php:1437
865
+ msgid "Montserrat"
866
+ msgstr ""
867
+
868
+ #: admin/class-admin.php:1438
869
+ msgid "Morocco"
870
+ msgstr ""
871
+
872
+ #: admin/class-admin.php:1439
873
+ msgid "Mozambique"
874
+ msgstr ""
875
+
876
+ #: admin/class-admin.php:1440
877
+ msgid "Myanmar"
878
+ msgstr ""
879
+
880
+ #: admin/class-admin.php:1441
881
+ msgid "Namibia"
882
+ msgstr ""
883
+
884
+ #: admin/class-admin.php:1442
885
+ msgid "Nauru"
886
+ msgstr ""
887
+
888
+ #: admin/class-admin.php:1443
889
+ msgid "Nepal"
890
+ msgstr ""
891
+
892
+ #: admin/class-admin.php:1444
893
+ msgid "Netherlands"
894
+ msgstr ""
895
+
896
+ #: admin/class-admin.php:1445
897
+ msgid "Netherlands Antilles"
898
+ msgstr ""
899
+
900
+ #: admin/class-admin.php:1446
901
+ msgid "New Zealand"
902
+ msgstr ""
903
+
904
+ #: admin/class-admin.php:1447
905
+ msgid "Nicaragua"
906
+ msgstr ""
907
+
908
+ #: admin/class-admin.php:1448
909
+ msgid "Niger"
910
+ msgstr ""
911
+
912
+ #: admin/class-admin.php:1449
913
+ msgid "Nigeria"
914
+ msgstr ""
915
+
916
+ #: admin/class-admin.php:1450
917
+ msgid "Niue"
918
+ msgstr ""
919
+
920
+ #: admin/class-admin.php:1451
921
+ msgid "Northern Mariana Islands"
922
+ msgstr ""
923
+
924
+ #: admin/class-admin.php:1452
925
+ msgid "Norway"
926
+ msgstr ""
927
+
928
+ #: admin/class-admin.php:1453
929
+ msgid "Oman"
930
+ msgstr ""
931
+
932
+ #: admin/class-admin.php:1454
933
+ msgid "Pakistan"
934
+ msgstr ""
935
+
936
+ #: admin/class-admin.php:1455
937
+ msgid "Panama"
938
+ msgstr ""
939
+
940
+ #: admin/class-admin.php:1456
941
+ msgid "Papua New Guinea"
942
+ msgstr ""
943
+
944
+ #: admin/class-admin.php:1457
945
+ msgid "Paraguay"
946
+ msgstr ""
947
+
948
+ #: admin/class-admin.php:1458
949
+ msgid "Peru"
950
+ msgstr ""
951
+
952
+ #: admin/class-admin.php:1459
953
+ msgid "Philippines"
954
+ msgstr ""
955
+
956
+ #: admin/class-admin.php:1460
957
+ msgid "Pitcairn Islands"
958
+ msgstr ""
959
+
960
+ #: admin/class-admin.php:1461
961
+ msgid "Poland"
962
+ msgstr ""
963
+
964
+ #: admin/class-admin.php:1462
965
+ msgid "Portugal"
966
+ msgstr ""
967
+
968
+ #: admin/class-admin.php:1463
969
+ msgid "Qatar"
970
+ msgstr ""
971
+
972
+ #: admin/class-admin.php:1464
973
+ msgid "Reunion"
974
+ msgstr ""
975
+
976
+ #: admin/class-admin.php:1465
977
+ msgid "Romania"
978
+ msgstr ""
979
+
980
+ #: admin/class-admin.php:1466
981
+ msgid "Russia"
982
+ msgstr ""
983
+
984
+ #: admin/class-admin.php:1467
985
+ msgid "Rwanda"
986
+ msgstr ""
987
+
988
+ #: admin/class-admin.php:1468
989
+ msgid "Saint Helena"
990
+ msgstr ""
991
+
992
+ #: admin/class-admin.php:1469
993
+ msgid "Saint Kitts and Nevis"
994
+ msgstr ""
995
+
996
+ #: admin/class-admin.php:1470
997
+ msgid "Saint Vincent and the Grenadines"
998
+ msgstr ""
999
+
1000
+ #: admin/class-admin.php:1471
1001
+ msgid "Saint Lucia"
1002
+ msgstr ""
1003
+
1004
+ #: admin/class-admin.php:1472
1005
+ msgid "Samoa"
1006
+ msgstr ""
1007
+
1008
+ #: admin/class-admin.php:1473
1009
+ msgid "San Marino"
1010
+ msgstr ""
1011
+
1012
+ #: admin/class-admin.php:1474
1013
+ msgid "São Tomé and Príncipe"
1014
+ msgstr ""
1015
+
1016
+ #: admin/class-admin.php:1475
1017
+ msgid "Saudi Arabia"
1018
+ msgstr ""
1019
+
1020
+ #: admin/class-admin.php:1476
1021
+ msgid "Senegal"
1022
+ msgstr ""
1023
+
1024
+ #: admin/class-admin.php:1477
1025
+ msgid "Serbia"
1026
+ msgstr ""
1027
+
1028
+ #: admin/class-admin.php:1478
1029
+ msgid "Seychelles"
1030
+ msgstr ""
1031
+
1032
+ #: admin/class-admin.php:1479
1033
+ msgid "Sierra Leone"
1034
+ msgstr ""
1035
+
1036
+ #: admin/class-admin.php:1480
1037
+ msgid "Singapore"
1038
+ msgstr ""
1039
+
1040
+ #: admin/class-admin.php:1481
1041
+ msgid "Slovakia"
1042
+ msgstr ""
1043
+
1044
+ #: admin/class-admin.php:1482
1045
+ msgid "Solomon Islands"
1046
+ msgstr ""
1047
+
1048
+ #: admin/class-admin.php:1483
1049
+ msgid "Somalia"
1050
+ msgstr ""
1051
+
1052
+ #: admin/class-admin.php:1484
1053
+ msgid "South Africa"
1054
+ msgstr ""
1055
+
1056
+ #: admin/class-admin.php:1485
1057
+ msgid "South Korea"
1058
+ msgstr ""
1059
+
1060
+ #: admin/class-admin.php:1486
1061
+ msgid "Spain"
1062
+ msgstr ""
1063
+
1064
+ #: admin/class-admin.php:1487
1065
+ msgid "Sri Lanka"
1066
+ msgstr ""
1067
+
1068
+ #: admin/class-admin.php:1488
1069
+ msgid "Sudan"
1070
+ msgstr ""
1071
+
1072
+ #: admin/class-admin.php:1489
1073
+ msgid "Swaziland"
1074
+ msgstr ""
1075
+
1076
+ #: admin/class-admin.php:1490
1077
+ msgid "Sweden"
1078
+ msgstr ""
1079
+
1080
+ #: admin/class-admin.php:1491
1081
+ msgid "Switzerland"
1082
+ msgstr ""
1083
+
1084
+ #: admin/class-admin.php:1492
1085
+ msgid "Syria"
1086
+ msgstr ""
1087
+
1088
+ #: admin/class-admin.php:1493
1089
+ msgid "Taiwan"
1090
+ msgstr ""
1091
+
1092
+ #: admin/class-admin.php:1494
1093
+ msgid "Tajikistan"
1094
+ msgstr ""
1095
+
1096
+ #: admin/class-admin.php:1495
1097
+ msgid "Tanzania"
1098
+ msgstr ""
1099
+
1100
+ #: admin/class-admin.php:1496
1101
+ msgid "Thailand"
1102
+ msgstr ""
1103
+
1104
+ #: admin/class-admin.php:1497
1105
+ msgid "Timor-Leste"
1106
+ msgstr ""
1107
+
1108
+ #: admin/class-admin.php:1498
1109
+ msgid "Tokelau"
1110
+ msgstr ""
1111
+
1112
+ #: admin/class-admin.php:1499
1113
+ msgid "Togo"
1114
+ msgstr ""
1115
+
1116
+ #: admin/class-admin.php:1500
1117
+ msgid "Tonga"
1118
+ msgstr ""
1119
+
1120
+ #: admin/class-admin.php:1501
1121
+ msgid "Trinidad and Tobago"
1122
+ msgstr ""
1123
+
1124
+ #: admin/class-admin.php:1502
1125
+ msgid "Tunisia"
1126
+ msgstr ""
1127
+
1128
+ #: admin/class-admin.php:1503
1129
+ msgid "Turkey"
1130
+ msgstr ""
1131
+
1132
+ #: admin/class-admin.php:1504
1133
+ msgid "Turkmenistan"
1134
+ msgstr ""
1135
+
1136
+ #: admin/class-admin.php:1505
1137
+ msgid "Tuvalu"
1138
+ msgstr ""
1139
+
1140
+ #: admin/class-admin.php:1506
1141
+ msgid "Uganda"
1142
+ msgstr ""
1143
+
1144
+ #: admin/class-admin.php:1507
1145
+ msgid "Ukraine"
1146
+ msgstr ""
1147
+
1148
+ #: admin/class-admin.php:1508
1149
+ msgid "United Arab Emirates"
1150
+ msgstr ""
1151
+
1152
+ #: admin/class-admin.php:1509
1153
+ msgid "United Kingdom"
1154
+ msgstr ""
1155
+
1156
+ #: admin/class-admin.php:1510
1157
+ msgid "United States"
1158
+ msgstr ""
1159
+
1160
+ #: admin/class-admin.php:1511
1161
+ msgid "Uruguay"
1162
+ msgstr ""
1163
+
1164
+ #: admin/class-admin.php:1512
1165
+ msgid "Uzbekistan"
1166
+ msgstr ""
1167
+
1168
+ #: admin/class-admin.php:1513
1169
+ msgid "Wallis Futuna"
1170
+ msgstr ""
1171
+
1172
+ #: admin/class-admin.php:1514
1173
+ msgid "Venezuela"
1174
+ msgstr ""
1175
+
1176
+ #: admin/class-admin.php:1515
1177
+ msgid "Vietnam"
1178
+ msgstr ""
1179
+
1180
+ #: admin/class-admin.php:1516
1181
+ msgid "Yemen"
1182
+ msgstr ""
1183
+
1184
+ #: admin/class-admin.php:1517
1185
+ msgid "Zambia"
1186
+ msgstr ""
1187
+
1188
+ #: admin/class-admin.php:1518
1189
+ msgid "Zimbabwe"
1190
+ msgstr ""
1191
+
1192
+ #: admin/class-admin.php:1591
1193
+ msgid "Cannot determine the address at this location."
1194
+ msgstr ""
1195
+
1196
+ #: admin/class-admin.php:1592
1197
+ msgid "Geocode was not successful for the following reason: "
1198
+ msgstr ""
1199
+
1200
+ #: admin/class-admin.php:1593
1201
+ msgid "Security check failed, reload the page and try again."
1202
+ msgstr ""
1203
+
1204
+ #: admin/class-store-overview.php:30
1205
+ msgid "Store"
1206
+ msgstr ""
1207
+
1208
+ #: admin/class-store-overview.php:65
1209
+ msgid "No stores found"
1210
+ msgstr ""
1211
+
1212
+ #: admin/class-store-overview.php:95
1213
+ msgid "Active"
1214
+ msgstr ""
1215
+
1216
+ #: admin/class-store-overview.php:95
1217
+ msgid "Inactive"
1218
+ msgstr ""
1219
+
1220
+ #: admin/class-store-overview.php:97
1221
+ msgid "Edit"
1222
+ msgstr ""
1223
+
1224
+ #: admin/class-store-overview.php:135
1225
+ msgid "ID"
1226
+ msgstr ""
1227
+
1228
+ #: admin/class-store-overview.php:136
1229
+ msgid "Thumbnail"
1230
+ msgstr ""
1231
+
1232
+ #: admin/class-store-overview.php:137
1233
+ msgid "Name"
1234
+ msgstr ""
1235
+
1236
+ #: admin/class-store-overview.php:138
1237
+ msgid "Address"
1238
+ msgstr ""
1239
+
1240
+ #: admin/class-store-overview.php:139
1241
+ msgid "City"
1242
+ msgstr ""
1243
+
1244
+ #: admin/class-store-overview.php:140
1245
+ msgid "State"
1246
+ msgstr ""
1247
+
1248
+ #: admin/class-store-overview.php:141
1249
+ msgid "Zip"
1250
+ msgstr ""
1251
+
1252
+ #: admin/class-store-overview.php:142
1253
+ msgid "Status"
1254
+ msgstr ""
1255
+
1256
+ #: admin/class-store-overview.php:143
1257
+ msgid "Actions"
1258
+ msgstr ""
1259
+
1260
+ #: admin/class-store-overview.php:193
1261
+ msgid "deactivated"
1262
+ msgstr ""
1263
+
1264
+ #: admin/class-store-overview.php:194
1265
+ msgid "deactivating"
1266
+ msgstr ""
1267
+
1268
+ #: admin/class-store-overview.php:197
1269
+ msgid "activated"
1270
+ msgstr ""
1271
+
1272
+ #: admin/class-store-overview.php:198
1273
+ msgid "activating"
1274
+ msgstr ""
1275
+
1276
+ #: admin/class-store-overview.php:205
1277
+ msgid "There was a problem "
1278
+ msgstr ""
1279
+
1280
+ #: admin/class-store-overview.php:208
1281
+ msgid "Store(s) successfully "
1282
+ msgstr ""
1283
+
1284
+ #: admin/class-store-overview.php:229
1285
+ msgid "There was a problem removing the store(s), please try again."
1286
+ msgstr ""
1287
+
1288
+ #: admin/class-store-overview.php:232
1289
+ msgid "Store(s) successfully removed."
1290
+ msgstr ""
1291
+
1292
+ #: admin/class-store-overview.php:417
1293
+ msgid "Are you sure you want to delete this store?"
1294
+ msgstr ""
1295
+
1296
+ #: admin/class-store-overview.php:419
1297
+ msgid "Delete"
1298
+ msgstr ""
1299
+
1300
+ #: admin/class-store-overview.php:420
1301
+ msgid "Cancel"
1302
+ msgstr ""
1303
+
1304
+ #: admin/templates/add-store.php:13 admin/templates/edit-store.php:23
1305
+ msgid "Store details"
1306
+ msgstr ""
1307
+
1308
+ #: admin/templates/add-store.php:16 admin/templates/edit-store.php:35
1309
+ msgid "Store Name:"
1310
+ msgstr ""
1311
+
1312
+ #: admin/templates/add-store.php:20 admin/templates/edit-store.php:39
1313
+ msgid "Address:"
1314
+ msgstr ""
1315
+
1316
+ #: admin/templates/add-store.php:24 admin/templates/edit-store.php:43
1317
+ msgid "Address 2:"
1318
+ msgstr ""
1319
+
1320
+ #: admin/templates/add-store.php:28 admin/templates/edit-store.php:47
1321
+ msgid "City:"
1322
+ msgstr ""
1323
+
1324
+ #: admin/templates/add-store.php:32 admin/templates/edit-store.php:51
1325
+ msgid "State / Province:"
1326
+ msgstr ""
1327
+
1328
+ #: admin/templates/add-store.php:36 admin/templates/edit-store.php:55
1329
+ msgid "Zip Code:"
1330
+ msgstr ""
1331
+
1332
+ #: admin/templates/add-store.php:40 admin/templates/edit-store.php:59
1333
+ msgid "Country:"
1334
+ msgstr ""
1335
+
1336
+ #: admin/templates/add-store.php:45 admin/templates/edit-store.php:64
1337
+ msgid "Latitude:"
1338
+ msgstr ""
1339
+
1340
+ #: admin/templates/add-store.php:49 admin/templates/edit-store.php:68
1341
+ msgid "Longitude:"
1342
+ msgstr ""
1343
+
1344
+ #: admin/templates/add-store.php:53 admin/templates/edit-store.php:72
1345
+ msgid "Preview location on the map"
1346
+ msgstr ""
1347
+
1348
+ #: admin/templates/add-store.php:54 admin/templates/edit-store.php:73
1349
+ msgid "You can adjust the location by dragging the marker around"
1350
+ msgstr ""
1351
+
1352
+ #: admin/templates/add-store.php:65 admin/templates/edit-store.php:84
1353
+ msgid "Extra details"
1354
+ msgstr ""
1355
+
1356
+ #: admin/templates/add-store.php:68 admin/templates/edit-store.php:87
1357
+ #: admin/templates/map-settings.php:277
1358
+ msgid "Phone:"
1359
+ msgstr ""
1360
+
1361
+ #: admin/templates/add-store.php:72 admin/templates/edit-store.php:91
1362
+ #: admin/templates/map-settings.php:281
1363
+ msgid "Fax:"
1364
+ msgstr ""
1365
+
1366
+ #: admin/templates/add-store.php:76 admin/templates/edit-store.php:95
1367
+ msgid "Email:"
1368
+ msgstr ""
1369
+
1370
+ #: admin/templates/add-store.php:80 admin/templates/edit-store.php:99
1371
+ msgid "Url:"
1372
+ msgstr ""
1373
+
1374
+ #: admin/templates/add-store.php:84 admin/templates/edit-store.php:103
1375
+ msgid "Description:"
1376
+ msgstr ""
1377
+
1378
+ #: admin/templates/add-store.php:88 admin/templates/edit-store.php:107
1379
+ msgid "Operation Hours:"
1380
+ msgstr ""
1381
+
1382
+ #: admin/templates/add-store.php:94 admin/templates/edit-store.php:113
1383
+ msgid "Thumbnail:"
1384
+ msgstr ""
1385
+
1386
+ #: admin/templates/add-store.php:98 admin/templates/edit-store.php:125
1387
+ msgid "Change thumbnail"
1388
+ msgstr ""
1389
+
1390
+ #: admin/templates/add-store.php:99 admin/templates/edit-store.php:126
1391
+ msgid "Remove"
1392
+ msgstr ""
1393
+
1394
+ #: admin/templates/edit-store.php:14
1395
+ msgid "Edit "
1396
+ msgstr ""
1397
+
1398
+ #: admin/templates/edit-store.php:26
1399
+ msgid "Status:"
1400
+ msgstr ""
1401
+
1402
+ #: admin/templates/edit-store.php:29
1403
+ msgid "active"
1404
+ msgstr ""
1405
+
1406
+ #: admin/templates/edit-store.php:31
1407
+ msgid "inactive"
1408
+ msgstr ""
1409
+
1410
+ #: admin/templates/edit-store.php:135
1411
+ msgid "Update Store"
1412
+ msgstr ""
1413
+
1414
+ #: admin/templates/faq.php:6
1415
+ msgid "How do I show the store locator on my page?"
1416
+ msgstr ""
1417
+
1418
+ #: admin/templates/faq.php:8
1419
+ msgid ""
1420
+ "Add this shortcode <code>[wpsl]</code> to the page where you want to show "
1421
+ "the store locator."
1422
+ msgstr ""
1423
+
1424
+ #: admin/templates/faq.php:12
1425
+ msgid ""
1426
+ "The map doesn't display properly. It's either broken in half or doesn't load "
1427
+ "at all."
1428
+ msgstr ""
1429
+
1430
+ #: admin/templates/faq.php:14
1431
+ msgid ""
1432
+ "Make sure you have defined a start point for the map under settings -> map "
1433
+ "settings."
1434
+ msgstr ""
1435
+
1436
+ #: admin/templates/faq.php:18
1437
+ msgid ""
1438
+ "I get an error saying the \"sensor\" parameter specified in the request must "
1439
+ "be set to either \"true\" or \"false\"."
1440
+ msgstr ""
1441
+
1442
+ #: admin/templates/faq.php:20
1443
+ msgid ""
1444
+ "Make sure you don't have any security plugins, or custom functions running "
1445
+ "that strip away version numbers from file paths."
1446
+ msgstr ""
1447
+
1448
+ #: admin/templates/faq.php:24
1449
+ msgid "The store locator doesn't load, it only shows the number 1?"
1450
+ msgstr ""
1451
+
1452
+ #: admin/templates/faq.php:26
1453
+ msgid ""
1454
+ "This is most likely caused by your theme using ajax navigation ( the loading "
1455
+ "of content without reloading the page ), or a conflict with another plugin. "
1456
+ "Try to disable the ajax navigation in the theme settings, or deactivate the "
1457
+ "plugin that enables it to see if that solves the problem."
1458
+ msgstr ""
1459
+
1460
+ #: admin/templates/faq.php:27
1461
+ msgid ""
1462
+ "If you don't use ajax navigation, but do see the number 1 it's probably a "
1463
+ "conflict with another plugin. Try to disable the plugins one by one to see "
1464
+ "if one of them is causing a conflict."
1465
+ msgstr ""
1466
+
1467
+ #: admin/templates/faq.php:28
1468
+ #, php-format
1469
+ msgid ""
1470
+ "If you find a plugin or theme that causes a conflict, please report it on "
1471
+ "the <a href=\"%s\">support page</a>."
1472
+ msgstr ""
1473
+
1474
+ #: admin/templates/faq.php:32
1475
+ msgid "Why does it show the location I searched for in the wrong country?"
1476
+ msgstr ""
1477
+
1478
+ #: admin/templates/faq.php:34
1479
+ msgid ""
1480
+ "Some location names exist in more then one country, and Google will guess "
1481
+ "which one you mean. This can be fixed by setting the correct \"Map Region\" "
1482
+ "on the settings page -> \"API Settings\"."
1483
+ msgstr ""
1484
+
1485
+ #: admin/templates/map-settings.php:16
1486
+ msgid "API Settings"
1487
+ msgstr ""
1488
+
1489
+ #: admin/templates/map-settings.php:19
1490
+ msgid "API key:"
1491
+ msgstr ""
1492
+
1493
+ #: admin/templates/map-settings.php:20
1494
+ msgid "Optional"
1495
+ msgstr ""
1496
+
1497
+ #: admin/templates/map-settings.php:23
1498
+ msgid "Map language:"
1499
+ msgstr ""
1500
+
1501
+ #: admin/templates/map-settings.php:29
1502
+ msgid "Map region:"
1503
+ msgstr ""
1504
+
1505
+ #: admin/templates/map-settings.php:34
1506
+ #, php-format
1507
+ msgid ""
1508
+ "* A valid <a href=\"%s\">API key</a> allows you to monitor the API usage "
1509
+ "<br> and is required if you need to purchase additional quota."
1510
+ msgstr ""
1511
+
1512
+ #: admin/templates/map-settings.php:43
1513
+ msgid "Search Settings"
1514
+ msgstr ""
1515
+
1516
+ #: admin/templates/map-settings.php:46
1517
+ msgid "Distance unit:"
1518
+ msgstr ""
1519
+
1520
+ #: admin/templates/map-settings.php:50
1521
+ msgid "Max search results:"
1522
+ msgstr ""
1523
+
1524
+ #: admin/templates/map-settings.php:54
1525
+ msgid "Search radius options:"
1526
+ msgstr ""
1527
+
1528
+ #: admin/templates/map-settings.php:58
1529
+ msgid ""
1530
+ "If a user hovers over the search results, the corresponding marker will "
1531
+ "bounce?"
1532
+ msgstr ""
1533
+
1534
+ #: admin/templates/map-settings.php:61
1535
+ msgid "* The default value is set between the ( )"
1536
+ msgstr ""
1537
+
1538
+ #: admin/templates/map-settings.php:70
1539
+ msgid "Map Settings"
1540
+ msgstr ""
1541
+
1542
+ #: admin/templates/map-settings.php:73
1543
+ msgid "Attempt to auto-locate the user:"
1544
+ msgstr ""
1545
+
1546
+ #: admin/templates/map-settings.php:77
1547
+ msgid "Load all stores on page load:"
1548
+ msgstr ""
1549
+
1550
+ #: admin/templates/map-settings.php:81
1551
+ msgid "Start point: *"
1552
+ msgstr ""
1553
+
1554
+ #: admin/templates/map-settings.php:86
1555
+ msgid "Zoom level:"
1556
+ msgstr ""
1557
+
1558
+ #: admin/templates/map-settings.php:90
1559
+ msgid "Map type:"
1560
+ msgstr ""
1561
+
1562
+ #: admin/templates/map-settings.php:94
1563
+ msgid "Show the street view controls?"
1564
+ msgstr ""
1565
+
1566
+ #: admin/templates/map-settings.php:98
1567
+ msgid "Show the pan controls?"
1568
+ msgstr ""
1569
+
1570
+ #: admin/templates/map-settings.php:102
1571
+ msgid "Position of the map controls:"
1572
+ msgstr ""
1573
+
1574
+ #: admin/templates/map-settings.php:105
1575
+ msgid "Left"
1576
+ msgstr ""
1577
+
1578
+ #: admin/templates/map-settings.php:107
1579
+ msgid "Right"
1580
+ msgstr ""
1581
+
1582
+ #: admin/templates/map-settings.php:111
1583
+ msgid "Zoom control style:"
1584
+ msgstr ""
1585
+
1586
+ #: admin/templates/map-settings.php:114
1587
+ msgid "Small"
1588
+ msgstr ""
1589
+
1590
+ #: admin/templates/map-settings.php:116
1591
+ msgid "Large"
1592
+ msgstr ""
1593
+
1594
+ #: admin/templates/map-settings.php:119
1595
+ msgid ""
1596
+ "* Required field. If auto-locating the user is disabled or fails, the center "
1597
+ "of the provided city or country will be used as the initial starting point "
1598
+ "for the user."
1599
+ msgstr ""
1600
+
1601
+ #: admin/templates/map-settings.php:128
1602
+ msgid "Design Settings"
1603
+ msgstr ""
1604
+
1605
+ #: admin/templates/map-settings.php:131
1606
+ msgid "Store Locator height"
1607
+ msgstr ""
1608
+
1609
+ #: admin/templates/map-settings.php:135
1610
+ msgid "Max width for the infowindow"
1611
+ msgstr ""
1612
+
1613
+ #: admin/templates/map-settings.php:139
1614
+ msgid "Search field width"
1615
+ msgstr ""
1616
+
1617
+ #: admin/templates/map-settings.php:143
1618
+ msgid "Search and radius label width *"
1619
+ msgstr ""
1620
+
1621
+ #: admin/templates/map-settings.php:147
1622
+ msgid "Select template"
1623
+ msgstr ""
1624
+
1625
+ #: admin/templates/map-settings.php:151
1626
+ msgid "Hide the scrollbar?"
1627
+ msgstr ""
1628
+
1629
+ #: admin/templates/map-settings.php:155
1630
+ msgid "Show the limit results dropdown?"
1631
+ msgstr ""
1632
+
1633
+ #: admin/templates/map-settings.php:159
1634
+ msgid "Open links in a new window?"
1635
+ msgstr ""
1636
+
1637
+ #: admin/templates/map-settings.php:163
1638
+ msgid "Show a reset map button?"
1639
+ msgstr ""
1640
+
1641
+ #: admin/templates/map-settings.php:167
1642
+ msgid ""
1643
+ "When a user clicks on \"Directions\", open a new window and show the route "
1644
+ "on maps.google.com"
1645
+ msgstr ""
1646
+
1647
+ #: admin/templates/map-settings.php:171
1648
+ msgid "Show a \"More info\" link in the store listings?"
1649
+ msgstr ""
1650
+
1651
+ #: admin/templates/map-settings.php:175
1652
+ msgid "Where do you want to show the \"More info\" details?"
1653
+ msgstr ""
1654
+
1655
+ #: admin/templates/map-settings.php:179
1656
+ msgid "If a store url exists, make the store name clickable?"
1657
+ msgstr ""
1658
+
1659
+ #: admin/templates/map-settings.php:183
1660
+ msgid "Make the phone number clickable on mobile devices?"
1661
+ msgstr ""
1662
+
1663
+ #: admin/templates/map-settings.php:187
1664
+ msgid ""
1665
+ "If available for the current location, show a link to enable street view "
1666
+ "from the infowindow?"
1667
+ msgstr ""
1668
+
1669
+ #: admin/templates/map-settings.php:191
1670
+ msgid "Show a \"zoom to\" link in the infowindow?"
1671
+ msgstr ""
1672
+
1673
+ #: admin/templates/map-settings.php:195
1674
+ msgid "On pageload move the mousecursor to the input field. **"
1675
+ msgstr ""
1676
+
1677
+ #: admin/templates/map-settings.php:198
1678
+ msgid ""
1679
+ "* This is the text that is placed before the search input and radius dropdown"
1680
+ msgstr ""
1681
+
1682
+ #: admin/templates/map-settings.php:199
1683
+ msgid ""
1684
+ "** If the store locator is not placed at the top of the page, enabling this "
1685
+ "feature can result in the page sliding down."
1686
+ msgstr ""
1687
+
1688
+ #: admin/templates/map-settings.php:208
1689
+ msgid "Markers"
1690
+ msgstr ""
1691
+
1692
+ #: admin/templates/map-settings.php:212
1693
+ msgid "Enable marker clusters? *"
1694
+ msgstr ""
1695
+
1696
+ #: admin/templates/map-settings.php:216
1697
+ msgid "Max zoom level:"
1698
+ msgstr ""
1699
+
1700
+ #: admin/templates/map-settings.php:220
1701
+ msgid "Cluster size:"
1702
+ msgstr ""
1703
+
1704
+ #: admin/templates/map-settings.php:223
1705
+ msgid "* Recommended for maps with a large amounts of markers."
1706
+ msgstr ""
1707
+
1708
+ #: admin/templates/map-settings.php:232
1709
+ msgid "Store Editor Settings"
1710
+ msgstr ""
1711
+
1712
+ #: admin/templates/map-settings.php:235
1713
+ msgid "Default country that will be used on the \"Add Store\" page."
1714
+ msgstr ""
1715
+
1716
+ #: admin/templates/map-settings.php:246
1717
+ msgid "Labels"
1718
+ msgstr ""
1719
+
1720
+ #: admin/templates/map-settings.php:249
1721
+ msgid "Your location:"
1722
+ msgstr ""
1723
+
1724
+ #: admin/templates/map-settings.php:253
1725
+ msgid "Search radius:"
1726
+ msgstr ""
1727
+
1728
+ #: admin/templates/map-settings.php:257
1729
+ msgid "No results found:"
1730
+ msgstr ""
1731
+
1732
+ #: admin/templates/map-settings.php:261
1733
+ msgid "Search:"
1734
+ msgstr ""
1735
+
1736
+ #: admin/templates/map-settings.php:265
1737
+ msgid "Searching (preloader text):"
1738
+ msgstr ""
1739
+
1740
+ #: admin/templates/map-settings.php:269
1741
+ msgid "Results:"
1742
+ msgstr ""
1743
+
1744
+ #: admin/templates/map-settings.php:273
1745
+ msgid "More info:"
1746
+ msgstr ""
1747
+
1748
+ #: admin/templates/map-settings.php:285
1749
+ msgid "Hours:"
1750
+ msgstr ""
1751
+
1752
+ #: admin/templates/map-settings.php:289
1753
+ msgid "Start location:"
1754
+ msgstr ""
1755
+
1756
+ #: admin/templates/map-settings.php:293
1757
+ msgid "Get directions:"
1758
+ msgstr ""
1759
+
1760
+ #: admin/templates/map-settings.php:297
1761
+ msgid "Back:"
1762
+ msgstr ""
1763
+
1764
+ #: admin/templates/map-settings.php:301
1765
+ msgid "Reset:"
1766
+ msgstr ""
1767
+
1768
+ #: admin/templates/map-settings.php:305
1769
+ msgid "Street view:"
1770
+ msgstr ""
1771
+
1772
+ #: admin/templates/map-settings.php:309
1773
+ msgid "Zoom here:"
1774
+ msgstr ""
1775
+
1776
+ #: admin/templates/map-settings.php:313
1777
+ msgid "General error:"
1778
+ msgstr ""
1779
+
1780
+ #: admin/templates/map-settings.php:317
1781
+ msgid "Query limit error:"
1782
+ msgstr ""
1783
+
1784
+ #: admin/templates/map-settings.php:320
1785
+ #, php-format
1786
+ msgid ""
1787
+ "* You can raise the <a href=\"%s\">usage limit</a> by obtaining an API <a "
1788
+ "href=\"%s\">key</a>, <br> and fill in the \"API key\" field at the top of "
1789
+ "this page."
1790
+ msgstr ""
1791
+
1792
+ #: admin/templates/map-settings.php:326
1793
+ msgid "Update Settings"
1794
+ msgstr ""
1795
+
1796
+ #: wp-store-locator.php:298
1797
+ msgid "Show the store list below the map"
1798
+ msgstr ""
readme.txt CHANGED
@@ -2,12 +2,12 @@
2
  Contributors: tijmensmit
3
  Tags: google maps, store locator, business locations, geocoding, stores, geo
4
  Requires at least: 3.5
5
- Tested up to: 3.8.1
6
- Stable tag: 1.2.13
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl.html
9
 
10
- An easy to use location management system that enables users to search for nearby physical stores
11
 
12
  == Description ==
13
 
@@ -28,6 +28,7 @@ the language that is set in the admin panel.
28
  * Show Google Maps in different languages, this also influences the language for the driving directions
29
  * Show the driving directions to the stores
30
  * Users can filter the returned results by radius or max results
 
31
  * Customize the max results and search radius values that users can select
32
  * Customize map settings like the terrain type, location of the map controls and the default zoom level
33
  * Auto-locate the location of the user and show nearby stores
@@ -48,12 +49,24 @@ Add this shortcode [wpsl] to the page where you want to display the store locato
48
 
49
  = The map doesn't display properly. It's either broken in half or doesn't load at all. =
50
 
51
- Make sure you have defined a start point for the map under settings -> map settings
52
 
53
  = I get an error saying the 'sensor' parameter specified in the request must be set to either 'true' or 'false' =
54
 
55
  Make sure you don't have any security plugins, or custom functions running that strip away version numbers from file paths.
56
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  == Screenshots ==
59
 
@@ -65,6 +78,35 @@ Make sure you don't have any security plugins, or custom functions running that
65
 
66
  == Changelog ==
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  = 1.2.13 =
69
  * Fixed the store search not returning any results when the limit results dropdown is hidden
70
 
2
  Contributors: tijmensmit
3
  Tags: google maps, store locator, business locations, geocoding, stores, geo
4
  Requires at least: 3.5
5
+ Tested up to: 3.9.1
6
+ Stable tag: 1.2.20
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl.html
9
 
10
+ An easy to use location management system that enables users to search for nearby physical stores.
11
 
12
  == Description ==
13
 
28
  * Show Google Maps in different languages, this also influences the language for the driving directions
29
  * Show the driving directions to the stores
30
  * Users can filter the returned results by radius or max results
31
+ * Supports the clustering of markers
32
  * Customize the max results and search radius values that users can select
33
  * Customize map settings like the terrain type, location of the map controls and the default zoom level
34
  * Auto-locate the location of the user and show nearby stores
49
 
50
  = The map doesn't display properly. It's either broken in half or doesn't load at all. =
51
 
52
+ Make sure you have defined a start point for the map under settings -> Map Settings.
53
 
54
  = I get an error saying the 'sensor' parameter specified in the request must be set to either 'true' or 'false' =
55
 
56
  Make sure you don't have any security plugins, or custom functions running that strip away version numbers from file paths.
57
 
58
+ = Why does it show the location I searched for in the wrong country? =
59
+
60
+ Some location names exist in more then one country, and Google will guess which one you mean. This can be fixed by setting the correct 'Map Region' on the settings page -> API Settings.
61
+
62
+ = The store locator doesn't load, it only shows the number 1? =
63
+
64
+ This is most likely caused by your theme using ajax navigation ( the loading of content without reloading the page ), or a conflict with another plugin. Try to disable the ajax navigation in the theme settings, or deactivate the plugin that enables it to see if that solves the problem.
65
+
66
+ If you don't use ajax navigation, but do see the number 1 it's probably a conflict with another plugin. Try to disable the plugins one by one to see if one of them is causing a conflict.
67
+
68
+ If you find a plugin or theme that causes a conflict, please report it on the [support page](http://wordpress.org/support/plugin/wp-store-locator).
69
+
70
 
71
  == Screenshots ==
72
 
78
 
79
  == Changelog ==
80
 
81
+ = 1.2.20 =
82
+ * Fixed the directions url sometimes showing an incomplete address due to an encoding issue
83
+ * Fixed the 'items' count on the store overview page showing the incorrect number after deleting a store
84
+ * Fixed the autocomplete for the 'start point' field sometimes not working on the settings page
85
+ * Fixed php notices breaking the store search when wp_debug is set to true
86
+ * Fixed the bulk actions when set to 'Bulk Actions' showing the full store list without paging
87
+ * Fixed small css alignment issues in the admin area
88
+ * Fixed the js script still trying to load store data when autoload was disabled
89
+ * Fixed the clickable area around the marker being to big
90
+ * Improved: After a user clicks on 'directions' and then clicks 'back', the map view is returned to the original location
91
+ * Removed: the 'Preview location on the map' button no longer updates the zip code value it receives from the Google Maps API
92
+ * Changed the way the dropdown filters are handled on mobile devices. They are now styled and behave according to the default UI of the device
93
+ * Added support for WP Multisite
94
+ * Added 'Screen Options' for the 'Current Stores' page, so you can define the amount of stores that are visible on a single page
95
+ * Added the option to make phone numbers clickable on mobile devices by adding a link around them with 'tel:'
96
+ * Added the option to make store names automatically clickable if the store url exists
97
+ * Added the option to show a 'zoom here' and 'street view' (when available) into the infowindow
98
+ * Added a second address field to the store fields
99
+ * Added the option to enable marker clusters
100
+ * Added the option to set a default country for the "Add Store" page
101
+ * Added Dutch (nl_NL) translations
102
+ * Added a .pot file to the languages folder for translators
103
+ * Added error handling for the driving directions
104
+ * Added several filters for developers:
105
+ 'wpsl_templates' for loading a custom template from another directory
106
+ 'wpsl_menu_position' for adjusting the position of the store locator menu in the admin panel
107
+ 'wpsl_capability' to manually set the required user capability for adding/editing stores
108
+ 'wpsl_gmap_api_attributes' to modify the Google maps parameters ( change the map language dynamically )
109
+
110
  = 1.2.13 =
111
  * Fixed the store search not returning any results when the limit results dropdown is hidden
112
 
uninstall.php CHANGED
@@ -3,10 +3,28 @@ if ( !defined( 'ABSPATH' ) && !defined( 'WP_UNINSTALL_PLUGIN ') ) {
3
  exit;
4
  }
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  function wpsl_uninstall() {
7
 
8
- global $wpdb;
9
- global $current_user;
10
 
11
  $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'wpsl_stores' );
12
 
@@ -14,9 +32,5 @@ function wpsl_uninstall() {
14
  delete_option( 'wpsl_settings' );
15
 
16
  delete_user_meta( $current_user->ID, 'wpsl_disable_location_warning' );
17
-
18
- }
19
-
20
- /* Delete the tables and options from the db */
21
- wpsl_uninstall();
22
- ?>
3
  exit;
4
  }
5
 
6
+ /* Check if we need to run the uninstall for a single or mu installation */
7
+ if ( !is_multisite() ) {
8
+ wpsl_uninstall();
9
+ } else {
10
+
11
+ global $wpdb;
12
+
13
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
14
+ $original_blog_id = get_current_blog_id();
15
+
16
+ foreach ( $blog_ids as $blog_id ) {
17
+ switch_to_blog( $blog_id );
18
+ wpsl_uninstall();
19
+ }
20
+
21
+ switch_to_blog( $original_blog_id );
22
+ }
23
+
24
+ /* Delete the tables and options from the db */
25
  function wpsl_uninstall() {
26
 
27
+ global $wpdb, $current_user;
 
28
 
29
  $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'wpsl_stores' );
30
 
32
  delete_option( 'wpsl_settings' );
33
 
34
  delete_user_meta( $current_user->ID, 'wpsl_disable_location_warning' );
35
+ delete_user_meta( $current_user->ID, 'wpsl_stores_per_page' );
36
+ }
 
 
 
 
wp-store-locator.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI:
5
  Description: An easy to use location management system that enables users to search for nearby physical stores
6
  Author: Tijmen Smit
7
  Author URI: http://tijmensmit.com/
8
- Version: 1.2.13
9
  Text Domain: wpsl
10
  Domain Path: /languages/
11
  License: GPLv3
@@ -48,76 +48,29 @@ if ( !class_exists( 'WP_Store_locator' ) ) {
48
  * @since 1.0
49
  * @var array
50
  */
51
- public $default_settings = array(
52
- 'api_key' => '',
53
- 'api_language' => 'en',
54
- 'api_region' => '',
55
- 'distance_unit' => 'km',
56
- 'max_results' => '(25),50,75,100',
57
- 'search_radius' => '10,25,(50),100,200,500',
58
- 'marker_bounce' => '1',
59
- 'auto_locate' => '1',
60
- 'auto_load' => '1',
61
- 'zoom_level' => '3',
62
- 'zoom_name' => '',
63
- 'zoom_latlng' => '',
64
- 'height' => '350',
65
- 'map_type' => 'roadmap',
66
- 'pan_controls' => '0',
67
- 'streetview' => '0',
68
- 'results_dropdown' => '1',
69
- 'infowindow_width' => '225',
70
- 'search_width' => '179',
71
- 'label_width' => '95',
72
- 'control_position' => 'left',
73
- 'control_style' => 'small',
74
- 'new_window' => '0',
75
- 'reset_map' => '0',
76
- 'store_below' => '0',
77
- 'store_below_scroll' => '0',
78
- 'direction_redirect' => '0',
79
- 'more_info' => '0',
80
- 'more_info_location' => 'info window',
81
- 'mouse_focus' => '1',
82
- 'start_marker' => 'red.png',
83
- 'store_marker' => 'blue.png',
84
- 'start_label' => 'Start location',
85
- 'search_label' => 'Your location',
86
- 'search_btn_label' => 'Search',
87
- 'preloader_label' => 'Searching...',
88
- 'radius_label' => 'Search radius',
89
- 'no_results_label' => 'No results found',
90
- 'results_label' => 'Results',
91
- 'more_label' => 'More info',
92
- 'directions_label' => 'Directions',
93
- 'back_label' => 'Back',
94
- 'reset_label' => 'Reset',
95
- 'error_label' => 'Something went wrong, please try again!',
96
- 'limit_label' => 'API usage limit reached',
97
- 'phone_label' => 'Phone',
98
- 'fax_label' => 'Fax',
99
- 'hours_label' => 'Hours'
100
- );
101
 
102
  /**
103
  * Class constructor
104
  */
105
  function __construct() {
106
-
107
  $this->define_constants();
108
  $this->define_tables();
109
-
110
  if ( is_admin() ) {
111
  require_once( WPSL_PLUGIN_DIR . 'admin/class-admin.php' );
 
112
 
113
  load_plugin_textdomain( 'wpsl', false, basename( dirname( __FILE__ ) ) . '/languages' );
114
-
115
- register_activation_hook( __FILE__, array( $this, 'install' ) );
 
 
116
  } else {
117
  require_once( WPSL_PLUGIN_DIR . 'frontend/class-frontend.php' );
118
  }
119
 
120
- //if placed in the if else together with the class-frontend, the ajax hook always fails?
121
  require_once( WPSL_PLUGIN_DIR . 'frontend/wpsl-ajax-functions.php' );
122
  }
123
 
@@ -130,7 +83,7 @@ if ( !class_exists( 'WP_Store_locator' ) ) {
130
  public function define_constants() {
131
 
132
  if ( !defined( 'WPSL_VERSION_NUM' ) )
133
- define( 'WPSL_VERSION_NUM', '1.2.13' );
134
 
135
  if ( !defined( 'WPSL_URL' ) )
136
  define( 'WPSL_URL', plugin_dir_url( __FILE__ ) );
@@ -152,10 +105,41 @@ if ( !class_exists( 'WP_Store_locator' ) ) {
152
  /**
153
  * Run the install functions
154
  *
155
- * @since 1.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  * @return void
157
  */
158
- public function install() {
 
159
  $this->create_tables();
160
  $this->set_default_settings();
161
 
@@ -183,7 +167,8 @@ if ( !class_exists( 'WP_Store_locator' ) ) {
183
  $sql = "CREATE TABLE " . $wpdb->wpsl_stores . " (
184
  wpsl_id int(10) unsigned NOT NULL auto_increment,
185
  store varchar(255) NULL,
186
- street varchar(255) NULL,
 
187
  city varchar(255) NULL,
188
  state varchar(255) NULL,
189
  zip varchar(100) NULL,
@@ -221,6 +206,79 @@ if ( !class_exists( 'WP_Store_locator' ) ) {
221
  }
222
  }
223
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  /**
225
  * Get the current plugin settings
226
  *
@@ -237,10 +295,31 @@ if ( !class_exists( 'WP_Store_locator' ) ) {
237
  }
238
 
239
  return $settings;
240
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  }
242
 
243
  $wpsl = new WP_Store_locator();
244
- }
245
-
246
- ?>
5
  Description: An easy to use location management system that enables users to search for nearby physical stores
6
  Author: Tijmen Smit
7
  Author URI: http://tijmensmit.com/
8
+ Version: 1.2.20
9
  Text Domain: wpsl
10
  Domain Path: /languages/
11
  License: GPLv3
48
  * @since 1.0
49
  * @var array
50
  */
51
+ public $default_settings = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  /**
54
  * Class constructor
55
  */
56
  function __construct() {
57
+
58
  $this->define_constants();
59
  $this->define_tables();
60
+
61
  if ( is_admin() ) {
62
  require_once( WPSL_PLUGIN_DIR . 'admin/class-admin.php' );
63
+ require_once( WPSL_PLUGIN_DIR . 'admin/misc-functions.php' );
64
 
65
  load_plugin_textdomain( 'wpsl', false, basename( dirname( __FILE__ ) ) . '/languages' );
66
+
67
+ register_activation_hook( __FILE__, array( $this, 'run_install' ) );
68
+
69
+ $this->default_settings = $this->get_default_settings();
70
  } else {
71
  require_once( WPSL_PLUGIN_DIR . 'frontend/class-frontend.php' );
72
  }
73
 
 
74
  require_once( WPSL_PLUGIN_DIR . 'frontend/wpsl-ajax-functions.php' );
75
  }
76
 
83
  public function define_constants() {
84
 
85
  if ( !defined( 'WPSL_VERSION_NUM' ) )
86
+ define( 'WPSL_VERSION_NUM', '1.2.20' );
87
 
88
  if ( !defined( 'WPSL_URL' ) )
89
  define( 'WPSL_URL', plugin_dir_url( __FILE__ ) );
105
  /**
106
  * Run the install functions
107
  *
108
+ * @since 1.2.20
109
+ * @return void
110
+ */
111
+ public function run_install( $network_wide ) {
112
+
113
+ global $wpdb;
114
+
115
+ if ( function_exists( 'is_multisite' ) && is_multisite() ) {
116
+
117
+ if ( $network_wide ) {
118
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
119
+
120
+ foreach ( $blog_ids as $blog_id ) {
121
+ switch_to_blog( $blog_id );
122
+ $this->define_tables();
123
+ $this->install_data();
124
+ }
125
+
126
+ restore_current_blog();
127
+ } else {
128
+ $this->install_data();
129
+ }
130
+ } else {
131
+ $this->install_data();
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Create the required db and install the default settings and options values
137
+ *
138
+ * @since 1.2.20
139
  * @return void
140
  */
141
+ public function install_data() {
142
+
143
  $this->create_tables();
144
  $this->set_default_settings();
145
 
167
  $sql = "CREATE TABLE " . $wpdb->wpsl_stores . " (
168
  wpsl_id int(10) unsigned NOT NULL auto_increment,
169
  store varchar(255) NULL,
170
+ address varchar(255) NULL,
171
+ address2 varchar(255) NULL,
172
  city varchar(255) NULL,
173
  state varchar(255) NULL,
174
  zip varchar(100) NULL,
206
  }
207
  }
208
 
209
+ /**
210
+ * Get the default plugin settings
211
+ *
212
+ * @since 1.0
213
+ * @return void
214
+ */
215
+ public function get_default_settings() {
216
+
217
+ $default_settings = array (
218
+ 'api_key' => '',
219
+ 'api_language' => 'en',
220
+ 'api_region' => '',
221
+ 'distance_unit' => 'km',
222
+ 'max_results' => '(25),50,75,100',
223
+ 'search_radius' => '10,25,(50),100,200,500',
224
+ 'marker_bounce' => '1',
225
+ 'auto_locate' => '1',
226
+ 'auto_load' => '1',
227
+ 'zoom_level' => '3',
228
+ 'zoom_name' => '',
229
+ 'zoom_latlng' => '',
230
+ 'height' => '350',
231
+ 'map_type' => 'roadmap',
232
+ 'pan_controls' => '0',
233
+ 'streetview' => '0',
234
+ 'results_dropdown' => '1',
235
+ 'infowindow_width' => '225',
236
+ 'search_width' => '179',
237
+ 'label_width' => '95',
238
+ 'control_position' => 'left',
239
+ 'control_style' => 'small',
240
+ 'marker_clusters' => '0',
241
+ 'cluster_zoom' => '0',
242
+ 'cluster_size' => '0',
243
+ 'new_window' => '0',
244
+ 'reset_map' => '0',
245
+ 'template_id' => '0',
246
+ 'store_below_scroll' => '0',
247
+ 'direction_redirect' => '0',
248
+ 'more_info' => '0',
249
+ 'store_url' => '0',
250
+ 'phone_url' => '0',
251
+ 'marker_streetview' => '0',
252
+ 'marker_zoom_to' => '0',
253
+ 'more_info_location' => 'info window',
254
+ 'mouse_focus' => '1',
255
+ 'start_marker' => 'red.png',
256
+ 'store_marker' => 'blue.png',
257
+ 'editor_country' => '',
258
+ 'start_label' => __( 'Start location', 'wpsl' ),
259
+ 'search_label' => __( 'Your location', 'wpsl' ),
260
+ 'search_btn_label' => __( 'Search', 'wpsl' ),
261
+ 'preloader_label' => __( 'Searching...', 'wpsl' ),
262
+ 'radius_label' => __( 'Search radius', 'wpsl' ),
263
+ 'no_results_label' => __( 'No results found', 'wpsl' ),
264
+ 'results_label' => __( 'Results', 'wpsl' ),
265
+ 'more_label' => __( 'More info', 'wpsl' ),
266
+ 'directions_label' => __( 'Directions', 'wpsl' ),
267
+ 'no_directions_label' => __( 'No route could be found between the origin and destination', 'wpsl' ),
268
+ 'back_label' => __( 'Back', 'wpsl' ),
269
+ 'reset_label' => __( 'Reset', 'wpsl' ),
270
+ 'street_view_label' => __( 'Street view', 'wpsl' ),
271
+ 'zoom_here_label' => __( 'Zoom here', 'wpsl' ),
272
+ 'error_label' => __( 'Something went wrong, please try again!', 'wpsl' ),
273
+ 'limit_label' => __( 'API usage limit reached', 'wpsl' ),
274
+ 'phone_label' => __( 'Phone', 'wpsl' ),
275
+ 'fax_label' => __( 'Fax', 'wpsl' ),
276
+ 'hours_label' => __( 'Hours', 'wpsl' )
277
+ );
278
+
279
+ return $default_settings;
280
+ }
281
+
282
  /**
283
  * Get the current plugin settings
284
  *
295
  }
296
 
297
  return $settings;
298
+ }
299
+
300
+ /**
301
+ * Return a list of the default store templates
302
+ *
303
+ * @since 1.2.20
304
+ * @return array $templates The list of default store templates
305
+ */
306
+ public function get_templates() {
307
+
308
+ $templates = array (
309
+ array (
310
+ 'name' => __( 'Default', 'wpsl' ),
311
+ 'path' => WPSL_PLUGIN_DIR . 'frontend/templates/default.php'
312
+ ),
313
+ array (
314
+ 'name' => __( 'Show the store list below the map', 'wpsl' ),
315
+ 'path' => WPSL_PLUGIN_DIR . 'frontend/templates/store-listings-below.php'
316
+ )
317
+ );
318
+
319
+ return apply_filters( 'wpsl_templates', $templates );
320
+ }
321
+
322
  }
323
 
324
  $wpsl = new WP_Store_locator();
325
+ }