SaaS Dev Setup

Copy Production Database To Development

Create a copy of the production database from to development on AWS RDS.

Update MySLP AWS ECS Kit RDS Secrets

This assumes you have a local copy of the AWS ECS Kit repo.

ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/myslp-dashboard

Edit Docker/Composers/Secrets/docker-compose-rds-secrets.yml.

Change the WORDPRESS_DB_HOST to the new AWS RDS endpoint.

Update The Docker Image

Update The Submodules

First update the submodule data and loader files by opening a terminal window at the MySLP AWS ECS Kit root directory.

./tools/create_mustuseplugins_stubs.sh

When this finishes, update this repo and push to origin and the AWS CodeCommit directory via git. 

This will ensure the new submodule list is updated on the ECR Docker Image for the SLP SaaS product.

Build The ECR Image

Validate The ECR Login

aws sso login --profile lance.cleveland
aws ecr get-login-password --region us-east-1 --profile lance.cleveland | docker login --username AWS --password-stdin 744590032041.dkr.ecr.us-east-1.amazonaws.com/myslp2024-aarch64

Build The Image

cd ./Docker/Images
docker build --platform=linux/arm64 -t 744590032041.dkr.ecr.us-east-1.amazonaws.com/myslp2024-aarch64:develop .

This image is built with a local wildcard certificate for *.storelocatorplus.com.

The domain names it can serve via Apache are defined in 000-default.conf which includes:
* local.storelocatorplus.com
* test.storelocatorplus.com
* dashbeta.storelocatorplus.com
* dashboard.storelocatorplus.com

Push The Image To AWS ECR

docker push 744590032041.dkr.ecr.us-east-1.amazonaws.com/myslp2024-aarch64:develop

Running Containers Locally

This kit will allow you to not only build the baseline Docker image for MySLP2024 on the ARM64 (aarch64) architecture but it also provides a mechanism for using that image to launch various test environments on your laptop via named projects running a WordPress and MySQL host.

The local execution is managed via the Docker Compose files in ./Docker/Composers all commands should be executed there. Start with this command:

cd ./Docker/Composers

MySLP2024 Baked In

All the code is baked into the myslp2024-aarch64 image.

Data is served from the AWS RDS Dev MySQL server.

docker compose -f docker-compose-myslp2024-core-dev.yml -f Secrets/docker-compose-rds-secrets.yml -p myslp2024_bakedin up -d

MySLP2024 Local Source

Ensures a copy of the WordPress 6.4.2 code is available for debug tracing in ./Guest/wordpress for inline debugging with xDebug.

Overwrites the SLP specific code files with locally mapped files mounted via Volumes.

Data is served from the AWS RDS Dev MySQL server.

docker compose -f docker-compose-myslp2024-core-dev.yml -f docker-compose-myslp2024-use-localsource.yml -f Secrets/docker-compose-rds-secrets.yml -p myslp2024_localsource up -d

Accessing The Docker Container

Add an entry into /etc/hosts on your local system like this:

Go to MySLP2024 Baked In

All the code is baked into the myslp2024-aarch64 image.

Data is served from the AWS RDS Dev MySQL server.

docker compose -f docker-compose-myslp2024-core-dev.yml -f Secrets/docker-compose-rds-secrets.yml -p myslp2024_bakedin up

MySLP2024 Local Source

Ensures a copy of the WordPress 6.4.2 code is available for debug tracing in ./Guest/wordpress for inline debugging with xDebug.

Overwrites the SLP specific code files with locally mapped files mounted via Volumes.

Data is served from the AWS RDS Dev MySQL server.

docker compose -f docker-compose-myslp2024-core-dev.yml -f docker-compose-myslp2024-use-localsource.yml -f Secrets/docker-compose-rds-secrets.yml -p myslp2024_localsource up

Accessing The Build

Add an entry to /etc/hosts

127.0.0.1 localhost dev.storelocatorplus.com local.storelocatorplus.com localwp.storelocatorplus.com kubernetes.docker.internal kubernetes.docker.internal

Surf to https://local.storelocatorplus.com/

Upgrade The Network

If the core WordPress database engine has been changed you may need to login as a super admin for the SaaS platform and upgrade the network to ensure all the blog sites (customer accounts) are updated to the latest data structures.

SmartOptions

Smart Options via the SLP_SmartOptions class (include/module/smartoptions/SLP_SmartOptions.php) handles nearly all of the settings (options in WordPress parlance) for the Store Locator Plus® plugin.

Methods

get_ValueOf( <property:string> )

Get the value of a Smart Option.

		
Check if a given property exists and return the value.		
@param string $property The property to check.
@return bool Returns true if the property exists and is not null, and its 'is_true' property is true. Otherwise, returns false.

is_true( <property:string)

Check if a given property is true.
@param string $property The property to check.
@return bool Returns true if the property exists and is not null, and its ‘is_true’ property is true. Otherwise, returns false.

if ( SLP_SmartOptions::get_instance()->is_true( 'use_territory_bounds' ) ) {
    $this->add_territory_bounds();
}

Store Locator Plus® Staging (Prerelease) Updates 2024 Edition

We are going to move away from manually-executed grunt tasks via the wp-dev-kit repository and move toward an AWS implemented solution. We are going to leverage AWS developer tools to get the job done.

The general process is that you work on code and merge it into the develop branch of the store-locator-plus repository on CodeCommit (the main upstream source). When that code is deemed “ready for testing” the repo manager will merge the develop branch into the staging branch for the repository. CodePipeline should see the change to the staging branch in the repo and fire off the build and deployment processes.

CodeCommit

The repo, and now official “source of truth” for the SLP code and build kit repositories.

ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/store-locator-plus

The “upstream” aws repo for Store Locator Plus®.

CodeBuild

The build manager that will compile , minify, clean, and otherwise manipulate the stuff in the main SLP repo and prepare it for release. In this case a staging release of the WordPress plugin .zip file.

CodePipeline

Watches the main SLP repo for changes on the staging branch and fires off the CodeBuild execution when that happens.

Our pipeline is the store-locator-plus-staging-release pipeline. It has 3 stages:

Source

The CodeCommit source noted above.

Build

The CodeBuild project noted above.

Note that the CodePipeline takes over the artifact generation output and will dump the final output artifact store-locator-plus.zip into a different CodePipeline specific bucket. This is NOT the same bucket that is specified in the CodeBuild configuration.

Deploy

This is a setting in CodePipeline, NOT a CodeDeploy project, that copies the output artifact (store-locator-plus.zip) from the private CodePipeline artifacts bucket over into the storelocatorplus/builds/staging bucket.

S3 Buckets

This process uses S3 buckets to store build and pipeline artifacts.

The deployment process uses a public web endpoint (HTTP, non-secure) to store the final output artifact alongside some other SLP “goodies”.

The AWS S3 SLP storage site is: http://storelocatorplus.s3-website-us-east-1.amazonaws.com/

This bucket contains an index.html that has been created “by hand” to link to the staging and production zip files.

Image by 🌼Christel🌼 from Pixabay

PHP Documentation

Store Locator Plus® PHP Code Documentation

Generating The Documentation

The phpDocumentor tool is used to generate the docs via a Docker image. You will need Docker installed to generate the docs.

In the main plugins directory (~/phpStorm Projects/WordPress/wp-content/plugins) drop in the following phpdoc.dist.xml file. This version will generate documentation for the SLP and Power add on in a single HTML subsite.

Label Settings via Locator Layout

Use Case

The locator layout should be able to set any setting in SLP.

The Default Locator Style was updated to change “label_phone” from “Phone” to “Phone ” on the main Store Locator Plus® site (this is managed in the Premier Services plugin).

Problem

Setting the label_phone with a space at the end is not making it to the settings on a user site. It appears as though trim() is being called when the data is recieved.

Research

Cannot reproduce after fixing some JavaScript errors on the admin processor.

Debug: Results Phone Label Issue

Bug report

The Label for RESULTS PHONE is not appearing in front end

Recreation on QC

Set style on QC to “Default”.

Settings | Results | Results Layout:

<div id=”slp_results_[slp_location id]” class=”results_entry location_primary [slp_location featured]”> <div class=”results_row_left_column” id=”slp_left_cell_[slp_location id]” > [slp_addon section=primary position=first] <span class=”location_name”>[slp_location name] [slp_location uml_buttons] [slp_location gfi_buttons]</span> <span class=”location_distance”>[slp_location distance_1] [slp_location distance_unit]</span> [slp_addon section=primary position=last] </div> <div class=”results_row_center_column location_secondary” id=”slp_center_cell_[slp_location id]” > [slp_addon section=secondary position=first] <span class=”slp_result_address slp_result_street”>[slp_location address]</span> <span class=”slp_result_address slp_result_street2″>[slp_location address2]</span> <span class=”slp_result_address slp_result_citystatezip”>[slp_location city_state_zip]</span> <span class=”slp_result_address slp_result_country”>[slp_location country]</span> <div class=”contact_info”> <span class=”slp_result_address slp_result_phone”>[slp_location phone]</span> <span class=”slp_result_address slp_result_fax”>[slp_location fax]</span> </div> [slp_addon section=secondary position=last] </div> <div class=”results_row_right_column location_tertiary” id=”slp_right_cell_[slp_location id]” > [slp_addon section=tertiary position=first] <div class=”online_info”> <span class=”slp_result_contact slp_result_website”>[slp_location web_link]</span> <span class=”slp_result_contact slp_result_email”>[slp_location email_link]</span> <span class=”slp_result_contact slp_result_directions”><a href=”https://[slp_option map_domain]/maps?saddr=[slp_location search_address]&daddr=[slp_location location_address]” target=”_blank” class=”storelocatorlink”>[slp_location directions_text]</a></span> </div> <span class=”slp_result_contact slp_result_hours textblock”>[slp_location hours]</span> [slp_location pro_tags] [slp_location iconarray wrap=”fullspan”] [slp_location eventiconarray wrap=”fullspan”] [slp_location socialiconarray wrap=”fullspan”] [slp_addon section=tertiary position=last] </div> </div>

Settings | Results | Labels | Phone

Phone

Architecture: Update Plugin

FOR INTERNAL USE ONLY

The process that happens when a plugin is updated, especially the conversion of pre-existing options to SLPlus options / options_nojs serialized JSON objects.

In older releases , including some vestiges that still existing in 2209.X versions, options were stored in a WordPress option_name that match the plugin name. Such as option_name ‘slp-power’ for the power add on. Each add on had its own set of options.

When Smart Options were introduced into the SLP architecture there were two options that stored “all settings”. csl-slplus-options (aka “options”) stores settings that were not being localized and sent to JavaScript. csl-slplus-options_nojs (aka “options_nojs”) are the settings that are not localized. (In theory… both of these will be replaced with a single monolithic store in csl-slplus-options eventually and specific settings retrieved from JavaScript via a REST call).

The idea was to eventually (soon?) convert all separate plugin-specific option settings like option_name = ‘slp-power’ into a standard csl-slplus-options string. Below is the flowchart that describes how that conversion happens.

Store Locator Plus® JavaScript Pub/Sub

Store Locator Plus® was updated with a “pub/sub” model a few years ago. This feature is a managed interface for jQuery Callbacks that allows disparate Javascript functions to interact with each other. It works much like hooks and filters in WordPress, but solely within the JavaScript runtime space.

The basic premise is any JavaScript function can call a “publish” method that fires off a stack of callbacks.

slp_Filter('slp_map_ready').publish(cslmap);

What is run by those callbacks is set by having a JavaScript module call a “subscribe” method.

slp_Filter( 'slp_map_ready' ).subscribe( this.initialize );