Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/wp-store-locator/admin/EDD_SL_Plugin_Updater.php
+++ b/wp-store-locator/admin/EDD_SL_Plugin_Updater.php
@@ -5,6 +5,9 @@
exit;
}
+// @todo will be removed with v3 update.
+// we move to https://easydigitaldownloads.com/docs/software-licensing-updater-implementation-for-wordpress-plugins/
+
/**
* Allows plugins to use their own update API.
*
@@ -187,12 +190,8 @@
return;
}
- printf(
- '<tr class="plugin-update-tr %3$s" id="%1$s-update" data-slug="%1$s" data-plugin="%2$s">',
- $this->slug,
- $file,
- in_array( $this->name, $this->get_active_plugins(), true ) ? 'active' : 'inactive'
- );
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variables are escaped within printf.
+ printf( '<tr class="plugin-update-tr %3$s" id="%1$s-update" data-slug="%1$s" data-plugin="%2$s">', $this->slug, $file, in_array( $this->name, $this->get_active_plugins(), true ) ? 'active' : 'inactive' );
echo '<td colspan="3" class="plugin-update colspanchange">';
echo '<div class="update-message notice inline notice-warning notice-alt"><p>';
@@ -219,41 +218,26 @@
self_admin_url( 'update.php' )
);
- printf(
- /* translators: the plugin name. */
- esc_html__( 'There is a new version of %1$s available.', 'easy-digital-downloads' ),
- esc_html( $plugin['Name'] )
- );
+ /* translators: %1$s: the plugin name. */
+ printf( esc_html__( 'There is a new version of %1$s available.', 'wp-store-locator' ), esc_html( $plugin['Name'] ) );
if ( ! current_user_can( 'update_plugins' ) ) {
echo ' ';
- esc_html_e( 'Contact your network administrator to install the update.', 'easy-digital-downloads' );
+ esc_html_e( 'Contact your network administrator to install the update.', 'wp-store-locator' );
} elseif ( empty( $update_cache->response[ $this->name ]->package ) && ! empty( $changelog_link ) ) {
echo ' ';
- printf(
/* translators: 1. opening anchor tag, do not translate 2. the new plugin version 3. closing anchor tag, do not translate. */
- __( '%1$sView version %2$s details%3$s.', 'easy-digital-downloads' ),
- '<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
- esc_html( $update_cache->response[ $this->name ]->new_version ),
- '</a>'
- );
+ $view_details_text = __( '%1$sView version %2$s details%3$s.', 'wp-store-locator' );
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped within printf arguments.
+ printf( $view_details_text, '<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">', esc_html( $update_cache->response[ $this->name ]->new_version ), '</a>' );
} elseif ( ! empty( $changelog_link ) ) {
echo ' ';
- printf(
- __( '%1$sView version %2$s details%3$s or %4$supdate now%5$s.', 'easy-digital-downloads' ),
- '<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
- esc_html( $update_cache->response[ $this->name ]->new_version ),
- '</a>',
- '<a target="_blank" class="update-link" href="' . esc_url( wp_nonce_url( $update_link, 'upgrade-plugin_' . $file ) ) . '">',
- '</a>'
- );
+ /* translators: 1. opening anchor tag, do not translate 2. the new plugin version 3. closing anchor tag, do not translate 4. opening anchor tag, do not translate 5. closing anchor tag, do not translate. */
+ $view_details_or_update_text = __( '%1$sView version %2$s details%3$s or %4$supdate now%5$s.', 'wp-store-locator' );
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped within printf arguments.
+ printf( $view_details_or_update_text, '<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">', esc_html( $update_cache->response[ $this->name ]->new_version ), '</a>', '<a target="_blank" class="update-link" href="' . esc_url( wp_nonce_url( $update_link, 'upgrade-plugin_' . $file ) ) . '">','</a>' );
} else {
- printf(
- ' %1$s%2$s%3$s',
- '<a target="_blank" class="update-link" href="' . esc_url( wp_nonce_url( $update_link, 'upgrade-plugin_' . $file ) ) . '">',
- esc_html__( 'Update now.', 'easy-digital-downloads' ),
- '</a>'
- );
+ printf( ' %1$s%2$s%3$s', '<a target="_blank" class="update-link" href="' . esc_url( wp_nonce_url( $update_link, 'upgrade-plugin_' . $file ) ) . '">', esc_html__( 'Update now.', 'wp-store-locator' ), '</a>' );
}
do_action( "in_plugin_update_message-{$file}", $plugin, $plugin );
@@ -469,7 +453,7 @@
* If available, show the changelog for sites in a multisite install.
*/
public function show_changelog() {
-
+ // phpcs:disable WordPress.Security.NonceVerification.Recommended -- No nonce needed for read-only changelog display, capability check provides security.
if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' !== $_REQUEST['edd_sl_action'] ) {
return;
}
@@ -481,9 +465,10 @@
if ( empty( $_REQUEST['slug'] ) || $this->slug !== $_REQUEST['slug'] ) {
return;
}
+ // phpcs:enable WordPress.Security.NonceVerification.Recommended
if ( ! current_user_can( 'update_plugins' ) ) {
- wp_die( esc_html__( 'You do not have permission to install plugin updates', 'easy-digital-downloads' ), esc_html__( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
+ wp_die( esc_html__( 'You do not have permission to install plugin updates', 'wp-store-locator' ), esc_html__( 'Error', 'wp-store-locator' ), array( 'response' => 403 ) );
}
$version_info = $this->get_repo_api_data();
--- a/wp-store-locator/admin/blocks/wpsl-block/build/index.asset.php
+++ b/wp-store-locator/admin/blocks/wpsl-block/build/index.asset.php
@@ -0,0 +1 @@
+<?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'c9fd360d3e87ab4931bb');
--- a/wp-store-locator/admin/blocks/wpsl-map-block/build/index.asset.php
+++ b/wp-store-locator/admin/blocks/wpsl-map-block/build/index.asset.php
@@ -0,0 +1 @@
+<?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '7a4fd8f61026b3a96ea5');
--- a/wp-store-locator/admin/class-admin.php
+++ b/wp-store-locator/admin/class-admin.php
@@ -63,7 +63,6 @@
add_action( 'wp_loaded', array( $this, 'disable_setting_notices' ) );
add_action( 'wp_ajax_validate_server_key', array( $this, 'ajax_validate_server_key' ) );
- add_action( 'wp_ajax_nopriv_validate_server_key', array( $this, 'ajax_validate_server_key' ) );
}
/**
@@ -132,15 +131,26 @@
foreach ( $warnings as $setting_name => $warning ) {
if ( empty( $wpsl_settings[$setting_name] ) && !get_user_meta( $current_user->ID, 'wpsl_disable_' . $warning . '_warning' ) ) {
if ( $warning == 'key' ) {
- $this->setting_warning[$warning] = sprintf( __( "You need to create %sAPI keys%s for Google Maps before you can use the store locator! %sDismiss%s", "wpsl" ), '<a href="https://wpstorelocator.co/document/create-google-api-keys/">', "</a>", "<a href='" . esc_url( wp_nonce_url( add_query_arg( 'wpsl-notice', 'key' ), 'wpsl_notices_nonce', '_wpsl_notice_nonce' ) ) . "'>", "</a>" );
+ /* translators: %1$s: opening link tag, %2$s: closing link tag, %3$s: opening dismiss link tag, %4$s: closing link tag */
+ $this->setting_warning[$warning] = sprintf( __( 'You need to create %1$sAPI keys%2$s for Google Maps before you can use the store locator! %3$sDismiss%4$s', 'wp-store-locator' ), '<a href="https://wpstorelocator.co/document/create-google-api-keys/">', '</a>', "<a href='" . esc_url( wp_nonce_url( add_query_arg( 'wpsl-notice', 'key' ), 'wpsl_notices_nonce', '_wpsl_notice_nonce' ) ) . "'>", "</a>" );
} else {
- $this->setting_warning[$warning] = sprintf( __( "Before adding the [wpsl] shortcode to a page, please don't forget to define a start point on the %ssettings%s page. %sDismiss%s", "wpsl" ), "<a href='" . admin_url( 'edit.php?post_type=wpsl_stores&page=wpsl_settings' ) . "'>", "</a>", "<a href='" . esc_url( wp_nonce_url( add_query_arg( 'wpsl-notice', 'location' ), 'wpsl_notices_nonce', '_wpsl_notice_nonce' ) ) . "'>", "</a>" );
+ /* translators: %1$s: opening settings link tag, %2$s: closing link tag, %3$s: opening dismiss link tag, %4$s: closing link tag */
+ $this->setting_warning[$warning] = sprintf( __( 'Before adding the [wpsl] shortcode to a page, please don't forget to define a start point on the %1$ssettings%2$s page. %3$sDismiss%4$s', 'wp-store-locator' ), "<a href='" . admin_url( 'edit.php?post_type=wpsl_stores&page=wpsl_settings' ) . "'>", "</a>", "<a href='" . esc_url( wp_nonce_url( add_query_arg( 'wpsl-notice', 'location' ), 'wpsl_notices_nonce', '_wpsl_notice_nonce' ) ) . "'>", "</a>" );
}
}
}
if ( defined( 'WP_ROCKET_VERSION' ) && ! get_user_meta( $current_user->ID, 'wpsl_disable_wp_rocket_warning' ) ) {
- $this->setting_warning['wp_rocket'] = sprintf( __( "%sWP Store Locator:%s To prevent any conflicts the required JavaScript files are automatically excluded from WP Rocket. %s If the store locator map still breaks, then make sure to flush the cache by going to %sWP Rocket -> Clear and preload cache%s. %sDismiss%s", "wpsl" ), '<strong>', '</strong>', '<br><br>', '<strong>', '</strong>', "<a href='" . esc_url( wp_nonce_url( add_query_arg( 'wpsl-notice', 'wp_rocket' ), 'wpsl_notices_nonce', '_wpsl_notice_nonce' ) ) . "'>", "</a>" );
+ /* translators: %1$s: opening strong tag, %2$s: closing strong tag, %3$s: line break, %4$s: opening strong tag, %5$s: closing strong tag, %6$s: opening dismiss link tag, %7$s: closing link tag */
+ $this->setting_warning['wp_rocket'] = sprintf( __( '%1$sWP Store Locator:%2$s To prevent any conflicts the required JavaScript files are automatically excluded from WP Rocket. %3$s If the store locator map still breaks, then make sure to flush the cache by going to %4$sWP Rocket -> Clear and preload cache%5$s. %6$sDismiss%7$s', 'wp-store-locator' ), '<strong>', '</strong>', '<br><br>', '<strong>', '</strong>', "<a href='" . esc_url( wp_nonce_url( add_query_arg( 'wpsl-notice', 'wp_rocket' ), 'wpsl_notices_nonce', '_wpsl_notice_nonce' ) ) . "'>", "</a>" );
+ }
+
+ // Show WP Store Locator 3.0 beta notice
+ $v3_beta_dismissed = get_user_meta( $current_user->ID, 'wpsl_disable_v3_beta_warning', true );
+
+ if ( ! $v3_beta_dismissed ) {
+ /* translators: %1$s: opening link tag, %2$s: closing link tag, %3$s: opening dismiss link tag, %4$s: closing link tag */
+ $this->setting_warning['v3_beta'] = sprintf( __( 'Interested in getting notified when the beta version for WP Store Locator 3.0 is released? %1$sClick here%2$s. %3$sDismiss%4$s', 'wp-store-locator' ), '<a href="https://wpstorelocator.co/update-on-wp-store-locator-3-0/" target="_blank">', '</a>', "<a href='" . esc_url( wp_nonce_url( add_query_arg( 'wpsl-notice', 'v3_beta' ), 'wpsl_notices_nonce', '_wpsl_notice_nonce' ) ) . "'>", "</a>" );
}
if ( $this->setting_warning ) {
@@ -157,7 +167,7 @@
*/
public function show_warning() {
foreach ( $this->setting_warning as $k => $warning ) {
- echo "<div id='message' class='error'><p>" . $warning . "</p></div>";
+ echo '<div id="message" class="error"><p>' . wp_kses_post( $warning ) . '</p></div>';
}
}
@@ -174,13 +184,19 @@
if ( isset( $_GET['wpsl-notice'] ) && isset( $_GET['_wpsl_notice_nonce'] ) ) {
- if ( ! wp_verify_nonce( $_GET['_wpsl_notice_nonce'], 'wpsl_notices_nonce' ) ) {
- wp_die( __( 'Security check failed. Please reload the page and try again.', 'wpsl' ) );
+ if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpsl_notice_nonce'] ) ), 'wpsl_notices_nonce' ) ) {
+ wp_die( esc_html__( 'Security check failed. Please reload the page and try again.', 'wp-store-locator' ) );
}
- $notice = sanitize_text_field( $_GET['wpsl-notice'] );
-
- add_user_meta( $current_user->ID, 'wpsl_disable_' . $notice . '_warning', 'true', true );
+ $notice = sanitize_text_field( wp_unslash( $_GET['wpsl-notice'] ) );
+
+ $meta_key = 'wpsl_disable_' . $notice . '_warning';
+
+ update_user_meta( $current_user->ID, $meta_key, 'true' );
+
+ // Redirect to remove query parameters from URL
+ wp_safe_redirect( remove_query_arg( array( 'wpsl-notice', '_wpsl_notice_nonce' ) ) );
+ exit;
}
}
@@ -194,15 +210,15 @@
$sub_menus = apply_filters( 'wpsl_sub_menu_items', array(
array(
- 'page_title' => __( 'Settings', 'wpsl' ),
- 'menu_title' => __( 'Settings', 'wpsl' ),
+ 'page_title' => __( 'Settings', 'wp-store-locator' ),
+ 'menu_title' => __( 'Settings', 'wp-store-locator' ),
'caps' => 'manage_wpsl_settings',
'menu_slug' => 'wpsl_settings',
'function' => array( $this, 'load_template' )
),
array(
- 'page_title' => __( 'Add-Ons', 'wpsl' ),
- 'menu_title' => __( 'Add-Ons', 'wpsl' ),
+ 'page_title' => __( 'Add-Ons', 'wp-store-locator' ),
+ 'menu_title' => __( 'Add-Ons', 'wp-store-locator' ),
'caps' => 'manage_wpsl_settings',
'menu_slug' => 'wpsl_add_ons',
'function' => array( $this, 'load_template' )
@@ -225,7 +241,10 @@
*/
public function load_template() {
- switch ( $_GET['page'] ) {
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only checking which admin page to load, not processing form data
+ $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
+
+ switch ( $page ) {
case 'wpsl_settings':
require 'templates/map-settings.php';
break;
@@ -274,7 +293,8 @@
global $wpdb;
- $option_names = $wpdb->get_results( "SELECT option_name AS transient_name FROM " . $wpdb->options . " WHERE option_name LIKE ('_transient_wpsl_autoload_%')" );
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Intentional direct query to find and delete transients, caching not applicable
+ $option_names = $wpdb->get_results( $wpdb->prepare( "SELECT option_name AS transient_name FROM " . esc_sql( $wpdb->options ) . " WHERE option_name LIKE %s", '_transient_wpsl_autoload_%' ) );
if ( $option_names ) {
foreach ( $option_names as $option_name ) {
@@ -300,7 +320,7 @@
if ( ( version_compare( $wp_version, '3.8', '>=' ) == TRUE ) ) {
$min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
- wp_enqueue_style( 'wpsl-admin-38', plugins_url( '/css/style-3.8'. $min .'.css', __FILE__ ), false );
+ wp_enqueue_style( 'wpsl-admin-38', plugins_url( '/css/style-3.8'. $min .'.css', __FILE__ ), array(), WPSL_VERSION_NUM );
}
}
@@ -315,25 +335,31 @@
global $wpsl_settings;
$admin_js_l10n = array(
- 'noAddress' => __( 'Cannot determine the address at this location.', 'wpsl' ),
- 'geocodeFail' => __( 'Geocode was not successful for the following reason', 'wpsl' ),
- 'securityFail' => __( 'Security check failed, reload the page and try again.', 'wpsl' ),
- 'requiredFields' => __( 'Please fill in all the required store details.', 'wpsl' ),
- 'missingGeoData' => __( 'The map preview requires all the location details.', 'wpsl' ),
- 'closedDate' => __( 'Closed', 'wpsl' ),
- 'styleError' => __( 'The code for the map style is invalid.', 'wpsl' ),
- 'dismissNotice' => __( 'Dismiss this notice.', 'wpsl' ),
- 'browserKeyError' => sprintf( __( 'There's a problem with the provided %sbrowser key%s. %s You will have to open the %sbrowser console%s ( %sctrl%s %sshift%s %sk%s in Firefox, or %sctrl%s %sshift%s %sj%s in Chrome ) to see the error details returned by the Google Maps API. %s The error itself includes a link explaining the problem in more detail. %s Common API errors are also covered in the %stroubleshooting section%s.', 'wpsl' ), '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#browser-key">','</a>', '<br><br>', '<a target="_blank" href="https://codex.wordpress.org/Using_Your_Browser_to_Diagnose_JavaScript_Errors#Step_3:_Diagnosis">', '</a>', '<kbd>', '</kbd>', '<kbd>', '</kbd>','<kbd>', '</kbd>', '<kbd>', '</kbd>', '<kbd>', '</kbd>','<kbd>', '</kbd>', '<br><br>', '<br><br>', '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#api-errors">', '</a>' ),
- 'browserKeySuccess' => __( 'No problems found with the browser key.', 'wpsl' ),
- 'serverKey' => __( 'Server key', 'wpsl' ),
- 'serverKeyMissing' => sprintf( __( 'No %sserver key%s found!' ), '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#server-key">', '</a>' ),
- 'browserKey' => __( 'Browser key', 'wpsl' ),
- 'browserKeyMissing' => sprintf( __( 'No %sbrowser key%s found!' ), '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#browser-key">', '</a>' ),
- 'restrictedZipCode' => __( 'and will only work for zip codes.', 'wpsl' ),
- 'noRestriction' => sprintf( __( 'because no %smap region%s is selected the geocode API will search for matching results around the world. This may result in unexpected results.'), '<a class="wpsl-region-href" href="#wpsl-tabs">', '</a>' ),
- 'loadingError' => sprintf( __( 'Google Maps didn't load correctly. Make sure you have an active %sbilling%s %saccount%s for Google Maps. %s If the "For development purposes only" text keeps showing after creating a billing account, then you will have to contact %sGoogle Billing Support%s.', 'wpsl' ), '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#billing">', '</a>', '<a href="http://g.co/dev/maps-no-account">', '</a>', '<br><br>', '<a target="_blank" href="https://cloud.google.com/support/billing/">', '</a>' ),
- 'loadingFailed' => sprintf( __( 'Google Maps failed to load correctly. This is likely due to a problem with the provided %sbrowser key%s. %s You will have to open the %sbrowser console%s ( %sctrl%s %sshift%s %sk%s in Firefox, or %sctrl%s %sshift%s %sj%s in Chrome ) to see the error details returned by the Google Maps API. %s The error itself includes a link explaining the problem in more detail. %s Common API errors are also covered in the %stroubleshooting section%s.', 'wpsl' ), '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#browser-key">','</a>', '<br><br>', '<a target="_blank" href="https://codex.wordpress.org/Using_Your_Browser_to_Diagnose_JavaScript_Errors#Step_3:_Diagnosis">', '</a>', '<kbd>', '</kbd>', '<kbd>', '</kbd>','<kbd>', '</kbd>', '<kbd>', '</kbd>', '<kbd>', '</kbd>','<kbd>', '</kbd>', '<br><br>', '<br><br>', '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#api-errors">', '</a>' ),
- 'close' => __( 'Close', 'wpsl' ),
+ 'noAddress' => __( 'Cannot determine the address at this location.', 'wp-store-locator' ),
+ 'geocodeFail' => __( 'Geocode was not successful for the following reason', 'wp-store-locator' ),
+ 'securityFail' => __( 'Security check failed, reload the page and try again.', 'wp-store-locator' ),
+ 'requiredFields' => __( 'Please fill in all the required store details.', 'wp-store-locator' ),
+ 'missingGeoData' => __( 'The map preview requires all the location details.', 'wp-store-locator' ),
+ 'closedDate' => __( 'Closed', 'wp-store-locator' ),
+ 'styleError' => __( 'The code for the map style is invalid.', 'wp-store-locator' ),
+ 'dismissNotice' => __( 'Dismiss this notice.', 'wp-store-locator' ),
+ /* translators: %1$s: opening link tag, %2$s: closing link tag, %3$s: line break, %4$s: opening console link tag, %5$s: closing link tag, %6$s-%15$s: keyboard shortcuts markup, %16$s-%17$s: line breaks, %18$s: opening troubleshooting link tag, %19$s: closing link tag */
+ 'browserKeyError' => sprintf( __( 'There's a problem with the provided %1$sbrowser key%2$s. %3$s You will have to open the %4$sbrowser console%5$s ( %6$sctrl%7$s %8$sshift%9$s %10$sk%11$s in Firefox, or %12$sctrl%13$s %14$sshift%15$s %16$sj%17$s in Chrome ) to see the error details returned by the Google Maps API. %18$s The error itself includes a link explaining the problem in more detail. %19$s Common API errors are also covered in the %20$stroubleshooting section%21$s.', 'wp-store-locator' ), '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#browser-key">','</a>', '<br><br>', '<a target="_blank" href="https://codex.wordpress.org/Using_Your_Browser_to_Diagnose_JavaScript_Errors#Step_3:_Diagnosis">', '</a>', '<kbd>', '</kbd>', '<kbd>', '</kbd>','<kbd>', '</kbd>', '<kbd>', '</kbd>', '<kbd>', '</kbd>','<kbd>', '</kbd>', '<br><br>', '<br><br>', '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#api-errors">', '</a>' ),
+ 'browserKeySuccess' => __( 'No problems found with the browser key.', 'wp-store-locator' ),
+ 'serverKey' => __( 'Server key', 'wp-store-locator' ),
+ /* translators: %1$s: opening link tag, %2$s: closing link tag */
+ 'serverKeyMissing' => sprintf( __( 'No %1$sserver key%2$s found!', 'wp-store-locator' ), '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#server-key">', '</a>' ),
+ 'browserKey' => __( 'Browser key', 'wp-store-locator' ),
+ /* translators: %1$s: opening link tag, %2$s: closing link tag */
+ 'browserKeyMissing' => sprintf( __( 'No %1$sbrowser key%2$s found!', 'wp-store-locator' ), '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#browser-key">', '</a>' ),
+ 'restrictedZipCode' => __( 'and will only work for zip codes.', 'wp-store-locator' ),
+ /* translators: %1$s: opening link tag, %2$s: closing link tag */
+ 'noRestriction' => sprintf( __( 'because no %1$smap region%2$s is selected the geocode API will search for matching results around the world. This may result in unexpected results.', 'wp-store-locator' ), '<a class="wpsl-region-href" href="#wpsl-tabs">', '</a>' ),
+ /* translators: %1$s: opening billing link tag, %2$s: closing link tag, %3$s: opening account link tag, %4$s: closing link tag, %5$s: line break, %6$s: opening support link tag, %7$s: closing link tag */
+ 'loadingError' => sprintf( __( 'Google Maps didn't load correctly. Make sure you have an active %1$sbilling%2$s %3$saccount%4$s for Google Maps. %5$s If the "For development purposes only" text keeps showing after creating a billing account, then you will have to contact %6$sGoogle Billing Support%7$s.', 'wp-store-locator' ), '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#billing">', '</a>', '<a href="http://g.co/dev/maps-no-account">', '</a>', '<br><br>', '<a target="_blank" href="https://cloud.google.com/support/billing/">', '</a>' ),
+ /* translators: %1$s: opening link tag, %2$s: closing link tag, %3$s: line break, %4$s: opening console link tag, %5$s: closing link tag, %6$s-%15$s: keyboard shortcuts markup, %16$s-%17$s: line breaks, %18$s: opening troubleshooting link tag, %19$s: closing link tag */
+ 'loadingFailed' => sprintf( __( 'Google Maps failed to load correctly. This is likely due to a problem with the provided %1$sbrowser key%2$s. %3$s You will have to open the %4$sbrowser console%5$s ( %6$sctrl%7$s %8$sshift%9$s %10$sk%11$s in Firefox, or %12$sctrl%13$s %14$sshift%15$s %16$sj%17$s in Chrome ) to see the error details returned by the Google Maps API. %18$s The error itself includes a link explaining the problem in more detail. %19$s Common API errors are also covered in the %20$stroubleshooting section%21$s.', 'wp-store-locator' ), '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#browser-key">','</a>', '<br><br>', '<a target="_blank" href="https://codex.wordpress.org/Using_Your_Browser_to_Diagnose_JavaScript_Errors#Step_3:_Diagnosis">', '</a>', '<kbd>', '</kbd>', '<kbd>', '</kbd>','<kbd>', '</kbd>', '<kbd>', '</kbd>', '<kbd>', '</kbd>','<kbd>', '</kbd>', '<br><br>', '<br><br>', '<a target="_blank" href="https://wpstorelocator.co/document/create-google-api-keys/#api-errors">', '</a>' ),
+ 'close' => __( 'Close', 'wp-store-locator' ),
);
/**
@@ -347,7 +373,8 @@
$restriction_type = 'biased';
}
- $admin_js_l10n['resultsWarning'] = sprintf( __( 'with the current settings the results are %s to' ), $restriction_type );
+ /* translators: %s: restriction type (restricted or biased) */
+ $admin_js_l10n['resultsWarning'] = sprintf( __( 'with the current settings the results are %s to', 'wp-store-locator' ), $restriction_type );
}
return $admin_js_l10n;
@@ -371,7 +398,8 @@
'requiredFields' => array( 'address', 'city', 'country' ),
'ajaxurl' => wpsl_get_ajax_url(),
'url' => WPSL_URL,
- 'storeMarker' => $wpsl_settings['store_marker']
+ 'storeMarker' => $wpsl_settings['store_marker'],
+ 'validateKeyNonce' => wp_create_nonce( 'wpsl_validate_server_key' )
);
// Make sure that the Geocode API testing tool correctly restricts the results if required.
@@ -427,13 +455,14 @@
$this->check_icon_font_usage();
// Only enqueue the rest of the css/js files if we are on a page that belongs to the store locator.
- if ( ( get_post_type() == 'wpsl_stores' ) || ( isset( $_GET['post_type'] ) && ( $_GET['post_type'] == 'wpsl_stores' ) ) ) {
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only checking which admin page we're on, not processing form data
+ if ( ( get_post_type() == 'wpsl_stores' ) || ( isset( $_GET['post_type'] ) && ( sanitize_text_field( wp_unslash( $_GET['post_type'] ) ) == 'wpsl_stores' ) ) ) {
// Make sure no other Google Map scripts can interfere with the one from the store locator.
wpsl_deregister_other_gmaps();
- wp_enqueue_style( 'jquery-style', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css' );
- wp_enqueue_style( 'wpsl-admin-css', plugins_url( '/css/style'. $min .'.css', __FILE__ ), false );
+ wp_enqueue_style( 'wp-jquery-ui-dialog' );
+ wp_enqueue_style( 'wpsl-admin-css', plugins_url( '/css/style'. $min .'.css', __FILE__ ), array(), WPSL_VERSION_NUM );
wp_enqueue_media();
wp_enqueue_script( 'jquery-ui-dialog' );
@@ -481,8 +510,8 @@
*/
public function welcome_pointer_script() {
- $pointer_content = '<h3>' . __( 'Welcome to WP Store Locator', 'wpsl' ) . '</h3>';
- $pointer_content .= '<p>' . __( 'Sign up for the latest plugin updates and announcements.', 'wpsl' ) . '</p>';
+ $pointer_content = '<h3>' . __( 'Welcome to WP Store Locator', 'wp-store-locator' ) . '</h3>';
+ $pointer_content .= '<p>' . __( 'Sign up for the latest plugin updates and announcements.', 'wp-store-locator' ) . '</p>';
$pointer_content .= '<div id="mc_embed_signup" class="wpsl-mc-wrap" style="padding:0 15px; margin-bottom:13px;"><form action="//wpstorelocator.us10.list-manage.com/subscribe/post?u=34e4c75c3dc990d14002e19f6&id=4be03427d7" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate><div id="mc_embed_signup_scroll"><input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required style="margin-right:5px;width:230px;"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button"><div style="position: absolute; left: -5000px;"><input type="text" name="b_34e4c75c3dc990d14002e19f6_4be03427d7" tabindex="-1" value=""></div></div></form></div>';
?>
@@ -490,7 +519,7 @@
//<![CDATA[
jQuery( document ).ready( function( $ ) {
$( '#menu-posts-wpsl_stores' ).pointer({
- content: '<?php echo $pointer_content; ?>',
+ content: <?php echo wp_json_encode( $pointer_content ); ?>,
position: {
edge: 'left',
align: 'center'
@@ -526,7 +555,7 @@
public function add_action_links( $links, $file ) {
if ( strpos( $file, 'wp-store-locator.php' ) !== false ) {
- $settings_link = '<a href="' . admin_url( 'edit.php?post_type=wpsl_stores&page=wpsl_settings' ) . '" title="View WP Store Locator Settings">' . __( 'Settings', 'wpsl' ) . '</a>';
+ $settings_link = '<a href="' . admin_url( 'edit.php?post_type=wpsl_stores&page=wpsl_settings' ) . '" title="View WP Store Locator Settings">' . __( 'Settings', 'wp-store-locator' ) . '</a>';
array_unshift( $links, $settings_link );
}
@@ -545,8 +574,8 @@
if ( strpos( $file, 'wp-store-locator.php' ) !== false ) {
$new_links = array(
- '<a href="https://wpstorelocator.co/documentation/" title="View Documentation">'. __( 'Documentation', 'wpsl' ).'</a>',
- '<a href="https://wpstorelocator.co/add-ons/" title="View Add-Ons">'. __( 'Add-Ons', 'wpsl' ).'</a>'
+ '<a href="https://wpstorelocator.co/documentation/" title="View Documentation">'. __( 'Documentation', 'wp-store-locator' ).'</a>',
+ '<a href="https://wpstorelocator.co/add-ons/" title="View Add-Ons">'. __( 'Add-Ons', 'wp-store-locator' ).'</a>'
);
$links = array_merge( $links, $new_links );
@@ -568,7 +597,8 @@
// Only modify the footer text if we are on the settings page of the wp store locator.
if ( isset( $current_screen->id ) && $current_screen->id == 'wpsl_stores_page_wpsl_settings' ) {
- $text = sprintf( __( 'If you like this plugin please leave us a %s5 star%s rating.', 'wpsl' ), '<a href="https://wordpress.org/support/view/plugin-reviews/wp-store-locator?filter=5#postform" target="_blank"><strong>', '</strong></a>' );
+ /* translators: %1$s: opening link and strong tag, %2$s: closing strong and link tag */
+ $text = sprintf( __( 'If you like this plugin please leave us a %1$s5 star%2$s rating.', 'wp-store-locator' ), '<a href="https://wordpress.org/support/view/plugin-reviews/wp-store-locator?filter=5#postform" target="_blank"><strong>', '</strong></a>' );
}
return $text;
--- a/wp-store-locator/admin/class-block.php
+++ b/wp-store-locator/admin/class-block.php
@@ -0,0 +1,273 @@
+<?php
+/**
+ * Gutenberg Block class
+ *
+ * @author Tijmen Smit
+ * @since 2.3.0
+ */
+
+if ( ! defined( 'ABSPATH' ) ) exit;
+
+if ( ! class_exists( 'WPSL_Block' ) ) {
+
+ /**
+ * Handle the WPSL Gutenberg block
+ *
+ * @since 2.3.0
+ */
+ class WPSL_Block {
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ add_action( 'init', array( $this, 'register_block' ) );
+ add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );
+ add_filter( 'block_categories_all', array( $this, 'register_block_category' ), 10, 2 );
+ }
+
+ /**
+ * Register custom block category for WPSL blocks.
+ *
+ * @since 2.3.0
+ * @param array $categories Existing block categories.
+ * @param object $post Current post object.
+ * @return array Modified block categories.
+ */
+ public function register_block_category( $categories, $post ) {
+ return array_merge(
+ $categories,
+ array(
+ array(
+ 'slug' => 'wpsl',
+ 'title' => __( 'WP Store Locator', 'wp-store-locator' ),
+ 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 572 1000" width="24" height="24"><path d="M286 0C128 0 0 128 0 286c0 41 12 81 18 100l204 432c9 18 26 29 26 29s11 11 38 11 37-11 37-11 18-11 27-29l203-432c6-19 18-59 18-100C571 128 443 0 286 0zm0 429c-79 0-143-64-143-143s64-143 143-143 143 64 143 143-64 143-143 143z"/></svg>',
+ ),
+ )
+ );
+ }
+
+ /**
+ * Register the Gutenberg block.
+ *
+ * @since 2.3.0
+ * @return void
+ */
+ public function register_block() {
+
+ register_block_type( WPSL_PLUGIN_DIR . 'admin/blocks/wpsl-block', array(
+ 'render_callback' => array( $this, 'render_block' ),
+ ) );
+
+ register_block_type( WPSL_PLUGIN_DIR . 'admin/blocks/wpsl-map-block', array(
+ 'render_callback' => array( $this, 'render_map_block' ),
+ ) );
+ }
+
+ /**
+ * Server-side render callback for the block.
+ *
+ * Builds the [wpsl] shortcode from block attributes and returns the output.
+ *
+ * @since 2.3.0
+ * @param array $attributes Block attributes.
+ * @return string The rendered shortcode output.
+ */
+ public function render_block( $attributes ) {
+
+ $shortcode_atts = '';
+
+ if ( ! empty( $attributes['template'] ) ) {
+ $shortcode_atts .= ' template="' . esc_attr( $attributes['template'] ) . '"';
+ }
+
+ if ( ! empty( $attributes['start_location'] ) ) {
+ $shortcode_atts .= ' start_location="' . esc_attr( $attributes['start_location'] ) . '"';
+ }
+
+ if ( $attributes['auto_locate'] === 'true' || $attributes['auto_locate'] === 'false' ) {
+ $shortcode_atts .= ' auto_locate="' . esc_attr( $attributes['auto_locate'] ) . '"';
+ }
+
+ $has_category_restriction = ! empty( $attributes['category'] ) && is_array( $attributes['category'] );
+
+ if ( $has_category_restriction ) {
+ $shortcode_atts .= ' category="' . esc_attr( implode( ',', $attributes['category'] ) ) . '"';
+ }
+
+ if ( ! $has_category_restriction && ! empty( $attributes['category_filter_type'] ) ) {
+ $shortcode_atts .= ' category_filter_type="' . esc_attr( $attributes['category_filter_type'] ) . '"';
+ }
+
+ if ( ! $has_category_restriction && ! empty( $attributes['category_selection'] ) ) {
+ $shortcode_atts .= ' category_selection="' . esc_attr( $attributes['category_selection'] ) . '"';
+ }
+
+ if ( ! $has_category_restriction && $attributes['category_filter_type'] === 'checkboxes' && ! empty( $attributes['checkbox_columns'] ) ) {
+ $shortcode_atts .= ' checkbox_columns="' . esc_attr( $attributes['checkbox_columns'] ) . '"';
+ }
+
+ if ( ! empty( $attributes['map_type'] ) ) {
+ $shortcode_atts .= ' map_type="' . esc_attr( $attributes['map_type'] ) . '"';
+ }
+
+ if ( ! empty( $attributes['start_marker'] ) ) {
+ $shortcode_atts .= ' start_marker="' . esc_attr( $attributes['start_marker'] ) . '"';
+ }
+
+ if ( ! empty( $attributes['store_marker'] ) ) {
+ $shortcode_atts .= ' store_marker="' . esc_attr( $attributes['store_marker'] ) . '"';
+ }
+
+ return do_shortcode( '[wpsl' . $shortcode_atts . ']' );
+ }
+
+ /**
+ * Server-side render callback for the map block.
+ *
+ * Builds the [wpsl_map] shortcode from block attributes and returns the output.
+ *
+ * @since 2.3.0
+ * @param array $attributes Block attributes.
+ * @return string The rendered shortcode output.
+ */
+ public function render_map_block( $attributes ) {
+
+ $shortcode_atts = '';
+
+ if ( ! empty( $attributes['id'] ) ) {
+ $shortcode_atts .= ' id="' . esc_attr( $attributes['id'] ) . '"';
+ }
+
+ if ( ! empty( $attributes['category'] ) && is_array( $attributes['category'] ) ) {
+ $shortcode_atts .= ' category="' . esc_attr( implode( ',', $attributes['category'] ) ) . '"';
+ }
+
+ if ( ! empty( $attributes['width'] ) ) {
+ $shortcode_atts .= ' width="' . esc_attr( $attributes['width'] ) . '"';
+ }
+
+ if ( ! empty( $attributes['height'] ) ) {
+ $shortcode_atts .= ' height="' . esc_attr( $attributes['height'] ) . '"';
+ }
+
+ if ( ! empty( $attributes['zoom'] ) ) {
+ $shortcode_atts .= ' zoom="' . esc_attr( $attributes['zoom'] ) . '"';
+ }
+
+ if ( ! empty( $attributes['map_type'] ) ) {
+ $shortcode_atts .= ' map_type="' . esc_attr( $attributes['map_type'] ) . '"';
+ }
+
+ if ( $attributes['map_type_control'] !== '' ) {
+ $shortcode_atts .= ' map_type_control="' . esc_attr( $attributes['map_type_control'] ) . '"';
+ }
+
+ if ( ! empty( $attributes['map_style'] ) ) {
+ $shortcode_atts .= ' map_style="' . esc_attr( $attributes['map_style'] ) . '"';
+ }
+
+ if ( $attributes['street_view'] !== '' ) {
+ $shortcode_atts .= ' street_view="' . esc_attr( $attributes['street_view'] ) . '"';
+ }
+
+ if ( $attributes['scrollwheel'] !== '' ) {
+ $shortcode_atts .= ' scrollwheel="' . esc_attr( $attributes['scrollwheel'] ) . '"';
+ }
+
+ if ( ! empty( $attributes['control_position'] ) ) {
+ $shortcode_atts .= ' control_position="' . esc_attr( $attributes['control_position'] ) . '"';
+ }
+
+ return do_shortcode( '[wpsl_map' . $shortcode_atts . ']' );
+ }
+
+ /**
+ * Register REST API routes for block data.
+ *
+ * @since 2.3.0
+ * @return void
+ */
+ public function register_rest_routes() {
+
+ register_rest_route( 'wpsl/v1', '/block-data', array(
+ 'methods' => 'GET',
+ 'callback' => array( $this, 'get_block_data' ),
+ 'permission_callback' => function() {
+ return current_user_can( 'edit_posts' );
+ },
+ ) );
+ }
+
+ /**
+ * Return the data needed by the block editor.
+ *
+ * Includes templates, map types, categories, and marker images.
+ *
+ * @since 2.3.0
+ * @return WP_REST_Response
+ */
+ public function get_block_data() {
+
+ // Templates
+ $templates = wpsl_get_templates();
+ $template_data = array();
+
+ foreach ( $templates as $template ) {
+ $template_data[] = array(
+ 'id' => isset( $template['id'] ) ? $template['id'] : '',
+ 'name' => isset( $template['name'] ) ? $template['name'] : '',
+ );
+ }
+
+ // Map types
+ $map_types = wpsl_get_map_types();
+
+ // Categories
+ $terms = get_terms( array(
+ 'taxonomy' => 'wpsl_store_category',
+ 'hide_empty' => false,
+ ) );
+ $category_data = array();
+
+ if ( ! is_wp_error( $terms ) && $terms ) {
+ foreach ( $terms as $term ) {
+ $category_data[] = array(
+ 'slug' => $term->slug,
+ 'name' => $term->name,
+ );
+ }
+ }
+
+ // Markers
+ $marker_dir = apply_filters( 'wpsl_admin_marker_dir', WPSL_PLUGIN_DIR . 'img/markers/' );
+ $marker_url = ( defined( 'WPSL_MARKER_URI' ) ) ? WPSL_MARKER_URI : WPSL_URL . 'img/markers/';
+ $markers = array();
+
+ if ( is_dir( $marker_dir ) ) {
+ if ( $dh = opendir( $marker_dir ) ) {
+ while ( false !== ( $file = readdir( $dh ) ) ) {
+ if ( $file === '.' || $file === '..' || strpos( $file, '2x' ) !== false ) {
+ continue;
+ }
+
+ $markers[] = $file;
+ }
+
+ closedir( $dh );
+ sort( $markers );
+ }
+ }
+
+ return rest_ensure_response( array(
+ 'templates' => $template_data,
+ 'map_types' => $map_types,
+ 'categories' => $category_data,
+ 'markers' => $markers,
+ 'marker_url' => $marker_url,
+ ) );
+ }
+ }
+
+ new WPSL_Block();
+}
--- a/wp-store-locator/admin/class-exit-survey.php
+++ b/wp-store-locator/admin/class-exit-survey.php
@@ -35,12 +35,12 @@
*/
public function deactivate() {
- if ( empty( $_REQUEST['wpsl_nonce'] ) || ! wp_verify_nonce( $_REQUEST['wpsl_nonce'], 'wpsl_survey_nonce' ) ) {
+ if ( empty( $_REQUEST['wpsl_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['wpsl_nonce'] ) ), 'wpsl_survey_nonce' ) ) {
return;
}
- $reason = ( isset( $_REQUEST['wpsl_deactivation_reason'] ) ) ? $_REQUEST['wpsl_deactivation_reason'] : '';
- $feedback = ( isset( $_REQUEST['wpsl_deactivation_feedback'] ) ) ? $_REQUEST['wpsl_deactivation_feedback'] : '';
+ $reason = ( isset( $_REQUEST['wpsl_deactivation_reason'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['wpsl_deactivation_reason'] ) ) : '';
+ $feedback = ( isset( $_REQUEST['wpsl_deactivation_feedback'] ) ) ? sanitize_textarea_field( wp_unslash( $_REQUEST['wpsl_deactivation_feedback'] ) ) : '';
if ( $reason ) {
$args = array(
--- a/wp-store-locator/admin/class-geocode.php
+++ b/wp-store-locator/admin/class-geocode.php
@@ -77,16 +77,18 @@
return $location_data;
case 'ZERO_RESULTS':
- $msg = __( 'The Google Geocoding API returned no results for the supplied address. Please change the address and try again.', 'wpsl' );
+ $msg = __( 'The Google Geocoding API returned no results for the supplied address. Please change the address and try again.', 'wp-store-locator' );
break;
case 'OVER_QUERY_LIMIT':
- $msg = sprintf( __( 'You have reached the daily allowed geocoding limit, you can read more %shere%s.', 'wpsl' ), '<a target="_blank" href="https://developers.google.com/maps/documentation/geocoding/#Limits">', '</a>' );
+ /* translators: %1$s: opening link tag, %2$s: closing link tag */
+ $msg = sprintf( __( 'You have reached the daily allowed geocoding limit, you can read more %1$shere%2$s.', 'wp-store-locator' ), '<a target="_blank" href="https://developers.google.com/maps/documentation/geocoding/#Limits">', '</a>' );
break;
case 'REQUEST_DENIED':
- $msg = sprintf( __( 'The Google Geocoding API returned REQUEST_DENIED. %s', 'wpsl' ), $this->check_geocode_error_msg( $geocode_response ) );
+ /* translators: %s: error details */
+ $msg = sprintf( __( 'The Google Geocoding API returned REQUEST_DENIED. %s', 'wp-store-locator' ), $this->check_geocode_error_msg( $geocode_response ) );
break;
default:
- $msg = __( 'The Google Geocoding API failed to return valid data, please try again later.', 'wpsl' );
+ $msg = __( 'The Google Geocoding API failed to return valid data, please try again later.', 'wp-store-locator' );
break;
}
} else {
@@ -114,9 +116,11 @@
// If the problem is IP based, then show a different error msg.
if ( strpos( $geocode_response['error_message'], 'IP' ) !== false ) {
- $error_msg = sprintf( __( '%sError message: %s. %s Make sure the IP address mentioned in the error matches with the IP set as the %sreferrer%s for the server API key in the %sGoogle API Console%s.', 'wpsl' ), $breaks, $this->clickable_error_links( $geocode_response['error_message'] ), $breaks, '<a href="https://wpstorelocator.co/document/create-google-api-keys/#server-key-referrer">', '</a>', '<a href="https://console.developers.google.com">', '</a>' );
+ /* translators: %1$s: line break, %2$s: error message, %3$s: line break, %4$s: opening referrer link tag, %5$s: closing link tag, %6$s: opening console link tag, %7$s: closing link tag */
+ $error_msg = sprintf( __( '%1$sError message: %2$s. %3$s Make sure the IP address mentioned in the error matches with the IP set as the %4$sreferrer%5$s for the server API key in the %6$sGoogle API Console%7$s.', 'wp-store-locator' ), $breaks, $this->clickable_error_links( $geocode_response['error_message'] ), $breaks, '<a href="https://wpstorelocator.co/document/create-google-api-keys/#server-key-referrer">', '</a>', '<a href="https://console.developers.google.com">', '</a>' );
} else {
- $error_msg = sprintf( __( '%sError message: %s %s Check if your issue is covered in the %stroubleshooting%s section, if not, then please open a %ssupport ticket%s.', 'wpsl' ), $breaks, $this->clickable_error_links( $geocode_response['error_message'] ), $breaks, '<a href="https://wpstorelocator.co/document/create-google-api-keys/#troubleshooting">', '</a>', '<a href="https://wpstorelocator.co/support/">', '</a>' );
+ /* translators: %1$s: line break, %2$s: error message, %3$s: line break, %4$s: opening troubleshooting link tag, %5$s: closing link tag, %6$s: opening support link tag, %7$s: closing link tag */
+ $error_msg = sprintf( __( '%1$sError message: %2$s %3$s Check if your issue is covered in the %4$stroubleshooting%5$s section, if not, then please open a %6$ssupport ticket%7$s.', 'wp-store-locator' ), $breaks, $this->clickable_error_links( $geocode_response['error_message'] ), $breaks, '<a href="https://wpstorelocator.co/document/create-google-api-keys/#troubleshooting">', '</a>', '<a href="https://wpstorelocator.co/support/">', '</a>' );
}
} else {
$error_msg = '';
@@ -138,21 +142,28 @@
$response = wpsl_call_geocode_api( $address );
if ( is_wp_error( $response ) ) {
- $geo_response = sprintf( __( 'Something went wrong connecting to the Google Geocode API: %s %s Please try again later.', 'wpsl' ), $response->get_error_message(), '<br><br>' );
+ /* translators: %1$s: error message, %2$s: line break */
+ $geo_response = sprintf( __( 'Something went wrong connecting to the Google Geocode API: %1$s %2$s Please try again later.', 'wp-store-locator' ), $response->get_error_message(), '<br><br>' );
} else if ( $response['response']['code'] == 500 ) {
- $geo_response = sprintf( __( 'The Google Geocode API reported the following problem: error %s %s %s Please try again later.', 'wpsl' ), $response['response']['code'], $response['response']['message'], '<br><br>' );
+ /* translators: %1$s: error code, %2$s: error message, %3$s: line break */
+ $geo_response = sprintf( __( 'The Google Geocode API reported the following problem: error %1$s %2$s %3$s Please try again later.', 'wp-store-locator' ), $response['response']['code'], $response['response']['message'], '<br><br>' );
} else if ( $response['response']['code'] == 400 ) {
+ $data_issue = '';
// Check on which page the 400 error was triggered, and based on that adjust the msg.
- if ( isset( $_GET['page'] ) && $_GET['page'] == 'wpsl_csv' ) {
- $data_issue = sprintf( __( 'You can fix this by making sure the CSV file uses %sUTF-8 encoding%s.', 'wpsl' ), '<a href="https://wpstorelocator.co/document/csv-manager/#utf8">', '</a>' );
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only checking which admin page we're on, not processing form data
+ if ( isset( $_GET['page'] ) && sanitize_text_field( wp_unslash( $_GET['page'] ) ) == 'wpsl_csv' ) {
+ /* translators: %1$s: opening link tag, %2$s: closing link tag */
+ $data_issue = sprintf( __( 'You can fix this by making sure the CSV file uses %1$sUTF-8 encoding%2$s.', 'wp-store-locator' ), '<a href="https://wpstorelocator.co/document/csv-manager/#utf8">', '</a>' );
} else if ( !$address ) {
- $data_issue = __( 'You need to provide the details for either the address, city, state or country before the API can return coordinates.', 'wpsl' ); // this is only possible if the required fields are disabled with custom code.
+ $data_issue = __( 'You need to provide the details for either the address, city, state or country before the API can return coordinates.', 'wp-store-locator' ); // this is only possible if the required fields are disabled with custom code.
}
- $geo_response = sprintf( __( 'The Google Geocode API reported the following problem: error %s %s %s %s', 'wpsl' ), $response['response']['code'], $response['response']['message'], '<br><br>', $data_issue );
+ /* translators: %1$s: error code, %2$s: error message, %3$s: line break, %4$s: additional data issue message */
+ $geo_response = sprintf( __( 'The Google Geocode API reported the following problem: error %1$s %2$s %3$s %4$s', 'wp-store-locator' ), $response['response']['code'], $response['response']['message'], '<br><br>', $data_issue );
} else if ( $response['response']['code'] != 200 ) {
- $geo_response = sprintf( __( 'The Google Geocode API reported the following problem: error %s %s %s Please contact %ssupport%s if the problem persists.', 'wpsl' ), $response['response']['code'], $response['response']['message'], '<br><br>', '<a href="https://wpstorelocator.co/support/">', '</a>' );
+ /* translators: %1$s: error code, %2$s: error message, %3$s: line break, %4$s: opening support link tag, %5$s: closing link tag */
+ $geo_response = sprintf( __( 'The Google Geocode API reported the following problem: error %1$s %2$s %3$s Please contact %4$ssupport%5$s if the problem persists.', 'wp-store-locator' ), $response['response']['code'], $response['response']['message'], '<br><br>', '<a href="https://wpstorelocator.co/support/">', '</a>' );
} else {
$geo_response = json_decode( $response['body'], true );
}
--- a/wp-store-locator/admin/class-license-manager.php
+++ b/wp-store-locator/admin/class-license-manager.php
@@ -124,7 +124,8 @@
return;
}
- $license = sanitize_text_field( $_POST['wpsl_licenses'][ $this->item_shortname ] );
+ // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is done in process_license_form() before this method is called
+ $license = isset( $_POST['wpsl_licenses'][ $this->item_shortname ] ) ? sanitize_text_field( wp_unslash( $_POST['wpsl_licenses'][ $this->item_shortname ] ) ) : '';
// data to send in our API request.
$api_params = array(
@@ -180,7 +181,8 @@
$this->set_license_notice( $this->item_name . ' license deactivated.', 'updated' );
} else {
- $message = sprintf (__( 'The %s license failed to deactivate, please try again later or contact support!', 'wpsl' ), $this->item_name );
+ /* translators: %s: add-on name */
+ $message = sprintf (__( 'The %s license failed to deactivate, please try again later or contact support!', 'wp-store-locator' ), $this->item_name );
$this->set_license_notice( $message, 'error' );
}
}
@@ -206,7 +208,7 @@
// Make sure the response came back okay.
if ( is_wp_error( $response ) ) {
- $message = $response->get_error_message() . '. ' . __( 'Please try again later!', 'wpsl' );
+ $message = $response->get_error_message() . '. ' . __( 'Please try again later!', 'wp-store-locator' );
$this->set_license_notice( $message, 'error' );
} else {
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
@@ -254,16 +256,20 @@
switch ( $activation_errors ) {
case 'item_name_mismatch':
- $error_msg = sprintf( __( 'The %s license key does not belong to this add-on.', 'wpsl' ), $this->item_name );
+ /* translators: %s: add-on name */
+ $error_msg = sprintf( __( 'The %s license key does not belong to this add-on.', 'wp-store-locator' ), $this->item_name );
break;
case 'no_activations_left':
- $error_msg = sprintf( __( 'The %s license key does not have any activations left.', 'wpsl' ), $this->item_name );
+ /* translators: %s: add-on name */
+ $error_msg = sprintf( __( 'The %s license key does not have any activations left.', 'wp-store-locator' ), $this->item_name );
break;
case 'expired':
- $error_msg = sprintf( __( 'The %s license key is expired. Please renew it.', 'wpsl' ), $this->item_name );
+ /* translators: %s: add-on name */
+ $error_msg = sprintf( __( 'The %s license key is expired. Please renew it.', 'wp-store-locator' ), $this->item_name );
break;
default:
- $error_msg = sprintf( __( 'There was a problem activating the license key for the %s, please try again or contact support. Error code: %s', 'wpsl' ), $this->item_name, $activation_errors );
+ /* translators: %1$s: add-on name, %2$s: error code */
+ $error_msg = sprintf( __( 'There was a problem activating the license key for the %1$s, please try again or contact support. Error code: %2$s', 'wp-store-locator' ), $this->item_name, $activation_errors );
break;
}
--- a/wp-store-locator/admin/class-metaboxes.php
+++ b/wp-store-locator/admin/class-metaboxes.php
@@ -17,6 +17,8 @@
*/
class WPSL_Metaboxes {
+ private $store_data = array();
+
public function __construct() {
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
add_action( 'save_post', array( $this, 'save_post' ) );
@@ -33,13 +35,13 @@
global $pagenow;
- add_meta_box( 'wpsl-store-details', __( 'Store Details', 'wpsl' ), array( $this, 'create_meta_fields' ), 'wpsl_stores', 'normal', 'high' );
- add_meta_box( 'wpsl-map-preview', __( 'Store Map', 'wpsl' ), array( $this, 'map_preview' ), 'wpsl_stores', 'side' );
+ add_meta_box( 'wpsl-store-details', __( 'Store Details', 'wp-store-locator' ), array( $this, 'create_meta_fields' ), 'wpsl_stores', 'normal', 'high' );
+ add_meta_box( 'wpsl-map-preview', __( 'Store Map', 'wp-store-locator' ), array( $this, 'map_preview' ), 'wpsl_stores', 'side' );
$enable_option = apply_filters( 'wpsl_enable_export_option', true );
if ( $enable_option && $pagenow == 'post.php' ) {
- add_meta_box( 'wpsl-data-export', __( 'Export', 'wpsl' ), array( $this, 'export_data' ), 'wpsl_stores', 'side', 'low' );
+ add_meta_box( 'wpsl-data-export', __( 'Export', 'wp-store-locator' ), array( $this, 'export_data' ), 'wpsl_stores', 'side', 'low' );
}
}
@@ -54,56 +56,56 @@
global $wpsl_settings;
$meta_fields = array(
- __( 'Location', 'wpsl' ) => array(
+ __( 'Location', 'wp-store-locator' ) => array(
'address' => array(
- 'label' => __( 'Address', 'wpsl' ),
+ 'label' => __( 'Address', 'wp-store-locator' ),
'required' => true
),
'address2' => array(
- 'label' => __( 'Address 2', 'wpsl' )
+ 'label' => __( 'Address 2', 'wp-store-locator' )
),
'city' => array(
- 'label' => __( 'City', 'wpsl' ),
+ 'label' => __( 'City', 'wp-store-locator' ),
'required' => true
),
'state' => array(
- 'label' => __( 'State', 'wpsl' )
+ 'label' => __( 'State', 'wp-store-locator' )
),
'zip' => array(
- 'label' => __( 'Zip Code', 'wpsl' )
+ 'label' => __( 'Zip Code', 'wp-store-locator' )
),
'country' => array(
-