0 comments on “Store Locator Plus® Coding Best Practices”

Store Locator Plus® Coding Best Practices

Avoid Duplicate Code

When possible avoid duplicate code.

Duplicate code creates a larger code footprint to search through when trying to add new features are resolve bugs.

Duplicate code creates more workload for the PHP pre-compiler. This means it will consume more memory and processing time on every single PHP interaction.

Duplicate code consumes more space on disk, more space in the repositories, and in memory for processing.

Overall duplicate code makes the application less performant and more brittle.

0 comments on “google_maps script missing slp_core prerequisite”

google_maps script missing slp_core prerequisite

Notice: Function WP_Scripts::add was called incorrectly.

The script with the handle “google_maps” was enqueued with dependencies that are not registered: slp_core.

Reproduction


Dev Notes

SLP Architecture

slp_core (WordPress/wp-content/plugins/store-locator-plus/js/slp_core.js)

slp_core is the WordPress handle for the slp_core.js file.
slp_core.js is the primary Google maps interface between WordPress and JavaScript

Where the slp_core is found in store-locator-plus v2603.03.01

slp_core references in slp v2603.03.01

slp_core is REGISTERED here: \SLP_Actions::wp_enqueue_scripts
slp_core is currently only enqueued here: \SLP_UI::render_shortcode


google_maps (Google public Google Map JavaScript loader)

This loads a URL similar to:
https://maps.googleapis.com/maps/api/js?libraries=geometry,marker&v=quarterly&language=en&region=US&key=<GOOGLE_API_KEY>&loading=async

In the JavaScript this is referenced as google.maps.*

Google Maps is only enqueued here with the google_maps hook: \SLPlus::enqueue_google_maps_script
* @used-by \SLPlus::nqGoogleMaps
* @used-by \SLP_Actions::wp_enqueue_scripts
* @used-by \SLP_Admin_UI::initialize via the WordPress admin_enqueue_scripts hook

Non Admin Implementation

google_maps is used for users that are not logged in (non-admin) when rendering the SLPLUS shortcode.

This is managed via \SLP_UI::render_shortcode

\SLP_Power_UI::at_startup adds google_maps as a js_requirement (managed by \SLP_BaseClass_UI as part of normal UI interface management). This is likely unnecessary.

JavaScript References

  • SLP
    • js/slp_core.js
  • Power add on (slp-power)
    • slp-power_userinterface.js
  • Premier add on (slp-premier)
    • js/markerclusterer.js
    • slp-premier_userinterface.js
Admin Implementation

This is called on the slp_manage_locations (Location Details) admin page: \SLP_Admin_UI::initialize
via add_action( ‘admin_enqueue_scripts’, array( $this, ‘enqueue_slp_core_and_google_maps’ ) );

JavaScript References

  • SLP
    • js/slp_core.js
    • admin-locations-tab.js
  • Premier add on (slp-premier)
    • admin-locations-tab.js
    • admin-settings-tab.js
    • admin.js

AI Actions

Prompt

@amelia – We need to fix a script enqueue issue on the Location Details page
___
The script with the handle “google_maps” was enqueued with dependencies that are not registered: slp_core.
__

This error is caused because the WordPress script with the handle slp_core is not enqueued.

__

Option 1: We could enqueue this by calling \SLP_UI::render_shortcode

For the JavaScript in slp_core to be fully functional it requires localized variables.
Currently this only happens in \SLP_UI::render_shortcode
The problem is that \SLP_UI::render_shortcode has the extra overhead:
– Generating a large HTML output string
– Firing a slp_after_render_shortcode action
We only want the JavaScript variables configured and then localized via \SLP_UI::localize_script

If we use this method, we would need to bypass the HTML output and slp_after_render_shortcode action hook processing.

The best way to hook that would be to rewrite \SLP_Admin_UI::initialize to call a new method:
– Replace add_action( ‘admin_enqueue_scripts’, array( $this->slplus, ‘enqueue_google_maps_script’ ) );
– With add_action( ‘admin_enqueue_scripts’, array( $this, ‘enqueue_slp_core_and_google_maps’ ) );

Create a new method \SLP_UI::enqueue_slp_core
– Extracts the first chunk of \SLP_UI::render_shortcode up to the wp_enqueue_script( ‘slp_core’ );
– It needs to accept the parameters from \SLP_UI::render_shortcode

Create a new method \SLP_Admin_UI::enqueue_slp_core_and_google_maps
– call the new \SLP_UI::enqueue_slp_core method
– call \SLPlus::enqueue_google_maps_script

Update \SLP_UI::render_shortcode to call \SLP_UI::enqueue_slp_core to replace the code that was moved to the new \SLP_UI::enqueue_slp_core method

AI Results

\SLP_UI::register_slp_scripts_if_needed is a duplicate of \SLP_Actions::wp_enqueue_scripts.
This unnecessary extra code.
Duplicate code should be avoided when possible.

Created \SLP_UI::enqueue_slp_core with admin_safe flag resulting in inefficient architecture.
This is only called with the admin_safe flag from \SLP_Admin_UI::enqueue_slp_core_and_google_maps.
The register_slp_scripts_if_needed call in the admin_safe short circuit block can be put inline in the calling method as a call to \SLP_Actions::wp_enqueue_scripts.
The admin_safe only method localize_script_admin_safe could should be in SLP_Admin_UI as it is an admin only method: \SLP_Admin_UI::localize_script_admin_safe.
The wp_enqueue_script( ‘slp_core’ ); call can be in the calling method as well.
Returning the $attributes array is not necessary.

My fixes to the AI work:

Rip out the admin_safe short circuit from SLP_UI and place the equivalent code in SLP_Admin_UI as these updates only related to admin hooks. SLP_UI relates to non-admin code and should not have admin-only methods in there. Us nqGoogleMaps in admin as that can certainly load in async versus defer mode.

in SLP_Admin_UI

	public function enqueue_slp_core_and_google_maps( string $hook = '' ): void {
		$slp_actions = SLP_Actions::get_instance();
		$slp_actions->wp_enqueue_scripts(); // misnomer - registers the slp_core script

		$this->localize_script_admin_safe();
		wp_enqueue_script( 'slp_core' );

		$this->slplus->nqGoogleMaps( $hook );
	}

	/**
	 * Localize only the data needed for admin enqueue paths without invoking shortcode SmartOptions callbacks.
	 */
	private function localize_script_admin_safe(): void {
		$scriptData = array(
			'options'              => is_array( $this->slplus->options ) ? $this->slplus->options : array(),
			'environment'          => array(
				'addons'      => $this->slplus->AddOns->get_versions(),
				'slp_version' => SLPLUS_VERSION,
			),
			'plugin_url'           => SLPLUS_PLUGINURL,
			'ajaxurl'              => admin_url( 'admin-ajax.php' ),
			'nonce'                => wp_create_nonce( 'wp_rest' ),
			'apikey'               => SLPlus::get_instance()->get_apikey(),
			'rest_url'             => rest_url( 'store-locator-plus/v2/' ),
			'messages'             => $this->get_messages(),
			'shortcode_attributes' => $this->js_attributes,
		);

		ksort( $scriptData['options'] );
		wp_add_inline_script(
			'slp_core',
			'const slplus = ' . wp_json_encode( $scriptData )
		);
	}

	/**
	 * Set the messages for us in the JS array.
	 *
	 * @return string[]
	 */
	private function get_messages(): array {
		$messages = $this->slplus->Text->get_text_group( 'messages' );

		return apply_filters( 'slp_js_messages', $messages );
	}

In SLP_UI

Move the localize_script_admin_save to the SLP_Admin_UI module where it belongs. Have register_slp-scripts_if_needed method call SLP_Actions->wp_enqueue_scripts in SLP_Actions.

	private function register_slp_scripts_if_needed(): void {
		$slp_actions = SLP_Actions::get_instance();
		$slp_actions->wp_enqueue_scripts();
	}

Update

The latest update needs to be reviewed. It is calling enqueue_google_maps_script from \SLP_Admin_UI::initialize
With add_action( ‘admin_enqueue_scripts’, array( $this, ‘enqueue_slp_core_and_google_maps’ ) );

Need to look at Premier interfaces listed above for Google Maps interactions.

Settings | Map | Map Center Fallback

This should be showing the Google Map to show the map center.

0 comments on “SLP Did Not Initialize On White Black Classic Theme”

SLP Did Not Initialize On White Black Classic Theme

The main locator page with the [slplus] shortcode generates the same message:

“Store Locator Plus® did not initialize properly.”

Reproduction

  • Login as admin
  • Download and Activate the White Black Classic theme by Masino1967
  • Activate the SLP base plugin
  • Add a page and put the [slplus] shortcode on the page
0 comments on “WPSLP Widget Enqueue Script Problem”

WPSLP Widget Enqueue Script Problem

This issue is specific to the WordPress plugin stack and does not affect SaaS installations.

Widget areas are special places on a classic theme that can accept blocks — typically areas like your sidebar or footer. This guide will explain how to use widgets on your website.

Sites using modern block themes do not use widgets, so you won’t find Appearance → Widgets in your dashboard.

Without a theme that supports widgets, the only place you’ll get Appearance -> Widgets support is with the Power add on for the Store Pages “no store page” template. The “no store page” template has not been updated to use blocks instead of widgets.

0 comments on “AI Testing : Writing Cypress.IO Pagination Test”

AI Testing : Writing Cypress.IO Pagination Test

The ultimate objective for the project is to have AI write clear and concise end-to-end (E2E) test specifications in Cypress.IO.

Unlike standard PHP and JavaScript, which AI has become fairly proficient at when writing new code, it turns out writing Cypress test specifications appears to be a new challenge for AI. It is likely due to the fact that things like Cypress specifications are built on a myriad of higher level JavaScript layers, frameworks to be more precise, that are combined in novel ways. The AI has far less training with these models as few companies write E2E test cases for their applications and of those that do few publish online. These extra layers of logic also rely on some knowledge of the application output specifically the exact HTML structure that is rendered by the underlying SaaS application.

The theory we are testing in this research paper is that some AI models will be more proficient than others at writing complex Cypress.IO test specification. Our initial testing that led to this paper was the discovery that AI is straight up awful at writing Cypress test specifications. Even after multiple prompt revisions, AGENTS.md precursor rules to assist in writing better scripts, AI still struggles. We have yet to build an AI prompt stack that generates specifications that come anywhere close to a final proper specification.

This research is meant to find the best LLM as a foundation on which to build these prompt stacks.

0 comments on “\SLPlus::enqueue_google_maps_script – slp_core dependency is not loaded for Admin pages”

\SLPlus::enqueue_google_maps_script – slp_core dependency is not loaded for Admin pages

Notice: Function WP_Scripts::add was called incorrectly. The script with the handle “google_maps” was enqueued with dependencies that are not registered: slp_core. Please see Debugging in WordPressfor more information. (This message was added in version 6.9.1.) in /var/www/html/wp-includes/functions.php on line 6131

\SLPlus::enqueue_google_maps_script calls enqueue scripts with slp_core as a dependency but it is missing when going to the Store Locator Plus | Locations page in the admin panel.

0 comments on “My Profile | Subscription | Update Card”

My Profile | Subscription | Update Card

The pre-production release of the 2602.XX.YY versions of the SaaS are setup with a revised React-based subscription processor.

The My Profile | Subscription tab allows the user to…

  • Change the plan (upgrade, downgrade)
  • Update Card
  • Cancel Subscription

Update Card

The update card process appears to be calling the backend, however how Stripe stores payment data and how it is rendered has changed.

0 comments on “Contact Us Loading On Every Page”

Contact Us Loading On Every Page

When a user is logged in, the application stack is calling \MySLP_Contact_Us::initialize on every page load on the MySLP SaaS system. This should only be loaded when a user is interacting with the Contact Us page in the app.

This is being called via \MySLP_loader in the myslp-dashboard code. This happens when plugins_loaded action hooks are called from WordPress per this code block:

	// Load the Customer Profile module AFTER history logger (pri; 15)
	add_action( 'plugins_loaded', function () {
		/**
		 * @return void
		 */
		function myslp_customer_interfaces_loader(): void {
			require_once( MYSLP_PLUGIN_DIR . 'include/customer_profile/MySLP_Customer_Profile.php' );
			require_once( MYSLP_PLUGIN_DIR . 'include/MySLP_Contact_Us.php' );
			require_once( MYSLP_PLUGIN_DIR . 'include/MySLP_Customer_Maintenance.php' );

			MySLP_Contact_Us::get_instance();
		}

		myslp_customer_interfaces_loader();
	}, 15 );
0 comments on “My Profile | Notifications”

My Profile | Notifications

The My Profile page is rendered as a React component as of the 2601.XX release. This is invoke using the WordPress blocks system via the JavaScript wp scripts helper in package.json.

Related PHP Classes and Methods

My Profile is managed via the MySLP Dashboard repo (Store-Locator-Plus/myslp-dashboard).
The \MySLP_Customer_Profile class extends SLP_Base_ReactObject.
SLP_Base_ReactObject is the Store Locator Plus class that acts as the helper to wire PHP data to the JavaScript interface using the defined WordPress blocks system. WordPress blocks are , at their core, React components.

SLP_Base_ReactObject JavaScript Variable Population

This is handled via the extendReactVars method, which is usually extended by child classes.
The return PHP array end up populating the slpReact JavaScript variable.

Most of the MySLP (SaaS code) variables will return a sub-array named mySLP.
This results in the JavaScript variable slpReact.mySLP which contains SaaS specific variables.

For example:
$vars[‘mySLP’][‘subscription’] = $this->get_subscription_data();

The notifications stack uses the MySLP_Customer_Profile::add_notification to build an array of notification messages. These are then consumed by the React ProfilePanel component.

Related React Components

ProfilePanel in WordPress/wp-content/plugins/myslp-dashboard/src/profile/profile.tsx is the primary wrapper for the entire My Profile page React component.

Notifications are handled by a Snackbar component provided by the @mui/material React framework.
It is driven by the JavaScript variables slpReact.mySLP.notifications array.
Each element is an object with a message<string> and severity<string> property.
If the notifications array is not empty, the Snackbar opens and the message stack is displayed.
The severity element defines the style of the Snackbar message interface.

0 comments on “My Profile | Cancel Subscription Not Working”

My Profile | Cancel Subscription Not Working

This is an issue with the updates to the My Profile interface from the 2602.01.01 version of the SLP SaaS platform.

Going to My Profile | Cancel Subscription is no longer working. It appears to post to the backend for processing, but there is not notification of cancellation and there is no update to the status.

The My Profile | Subscription page after clicking “Cancel Subscription”.