Categories Bug

Reproduce

  • Login as Super Admin (SA)
  • menu item : MySLP / Customers
  • switch to <???>
  • menu item: SLP / Categories

Report

See screen shot as how it shows in Staging , on the Categories page,

a bunch of script under locations but only the first one Named Distribution shows the script

[19-Nov-2024 15:11:30 UTC] 
PHP Deprecated:  Creation of dynamic property SLP_Power_Category_Manager::$wp_categories_by_id is deprecated 
in /var/www/html/wp-content/
plugins/slp-power/include/module/category/SLP_Power_Category_Manager.php 
on line 274

MySLP_REST_API Ajax Not Initialized

Generate Embed is not populating the embed map as the REST API call is generating an internal error.

The MySLP_REST_API is expecting the SLP AJAX property to be set and it is null.

Related Call Stack

class.myslp.rest.api.php:438, MySLP_REST_API->get_options()
class.myslp.rest.api.php:279, MySLP_REST_API->get_map_options()
MySLP.php:257, MySLP->rest_dispatch_request_filter()
class-wp-hook.php:324, WP_Hook->apply_filters()
plugin.php:205, apply_filters()
class-wp-rest-server.php:1187, WP_REST_Server->respond_to_request()
class-wp-rest-server.php:1041, WP_REST_Server->dispatch()
class-wp-rest-server.php:431, WP_REST_Server->serve_request()
rest-api.php:424, rest_api_loaded()
class-wp-hook.php:324, WP_Hook->apply_filters()
class-wp-hook.php:348, WP_Hook->do_action()
plugin.php:565, do_action_ref_array()
class-wp.php:418, WP->parse_request()
class-wp.php:813, WP->main()
functions.php:1336, wp()
wp-blog-header.php:16, require()
index.php:17, {main}()

Dev Notes

Stack tracing…

  1. On the initial call the store-locator-plus.php MUP is called first an is loading with the initMySLP _jsonp call from the embed script.
  2. the SLPlus::initialize_after_plugins_loaded() is being called.
    • DOING_AJAX is not set, so createobject_AJAX() is not called.
  3. MySLP_REST_API->get_options() is called, which expects SLP->AJAX to be set, but it is not.

The front-end/locations.js is using jQuery.ajax() but it is calling a REST API url, not an AJAX listener endpoint… from the locations.js call…

Update the MySLP_REST_API->get_options() method to use SLP_Ajax::get_instance() to ensure that object is instantiated before use when not doing an AJAX call.

Use the main MySLP::getUserBlogId() to fetch blog IDs.
Use SLP_Ajax::get_instance() versus the uninitialized slplus->AjaxHandler to get the SLP AJAX instance.

slplus->AJAX (slplus->AJAX_Handler) was not initialized because the call is a REST call not an AJAX call.

SaaS Returning Wrong Location List

Users are seeing the wrong locations when logged in, seeing the main super admin locations.

Reproduction

  • Login as a super admin (CiCi?)
  • Bring up the customer list and switch to any customer (bhinson)

The default location list is not correct. For bhinson it shows 2 locations that belong to super admin. bhinson has 0 locations.

Testing Update : 2024.11.14

  • Correct locations show up on MySLP menu, but NOT the SLP menu.

Dev Notes

SaaS is using a custom REST endpoint to find locations: …/myslp/v2/locations

This is running a custom interface in the MySLP Dashboard defined wp-content/plugins/myslp-dashboard/include/class.myslp.rest.api.php which fetches locations from include/location/MySLP_Location.php get_locations();

This leverages wp-content/plugins/store-locator-plus/include/module/location/SLP_Location_Utilities.php to provide the location data interface.

In MySLP_Locations the slptbl is set in __construct() which may be too early.
it is coming back as wp_store_locator which is incorrect
It appears switch_to_blog() has not yet been called.
The call stack at this point..

switch_to_blog is called in MySLP class via perform_init_actions()
which is attached to the WP hook ‘init’ with no order of precedence set

SLP not returning proper locations

The SLP Location Manager is rendered via SLP_Admin_Locations::display_manage_locations_table()
./wp-content/plugins/store-locator-plus/include/module/admin/SLP_Admin_Locations.php

It is pulling locations vis the $slplus->database property which is an instantiation of SLP_Data::
./wp-content/plugins/store-locator-plus/include/module/data/SLP_Data.php

SLP_Data::initialize is setting the SLP_Data::from_slp_table property via SLP_Data::set_database_meta()
This pulls from SLP_Data::db which is an instantiation of the WordPress wpdb class. The table is set by adding wpdb->prefix to the ‘store_locator’ fixed string.

wpdb->prefix is not pulling the proper user prefix , likely due to switch_to_blog() not being called yet.

Call Sequence

  • store-locator-plus.php is loaded…
  • slp_setup_environment() is called…
  • SLPLUS::initialize() is executed
    • $this->database = new SLP_Data()
  • SLP_Actions::initialize()
    • add_action( ‘init’, array( $this, ‘init’ ), 11 );
  • SLP_Actions::init() via WP init hook
  • MySLP::perform_init_actions()

Resolution

MySLP

The main MySLP dashboard loader (wp-content/plugins/myslp-dashboard/myslp-dashboard.php) was initializing the MySLP_Location class which immediate set the properties for SLP table and Extendo table names.

This needed to be deferred until after the MySLP::perform_init_actions() was called.

Added a new method in MySLP_Location::perform_init_actions() that sets the slp and extendo class properties. It is called from within the MySLP::perform_init_actions() to ensure proper timing on the reading of those table names.

SLP

Initialize the $slplus->data (SLP_Data) object AFTER the user login, performing the setup in the init action hook within SLP_Actions.

Payment Method undefined In SysAdmin View Profile

Deprecated: str_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /var/www/html/wp-content/plugins/myslp-customer-maintenance/include/MySLP_SysAdmin_View_Profile.php on line 275

Reproduction

  • Login as SA
  • List Customers
  • Choose a customer , highlight the row and click “view profile” under the menu.

When the page renders the debug.log entry will show the message above.

Resolution

Stop Gap

A stop-gap measure is in place to default to text “stripe”, but we need to find out why the myslp->User object does not have a payment method set.

$payment_method = $myslp->User->payment_method ?? 'stripe';

Various PHP 8 Errors

Related To Blog ID Not Set

  • [08-Nov-2024 20:28:43 UTC] PHP Warning: Undefined variable $user_blog in /var/www/html/wp-content/plugins/myslp-customer-maintenance/include/MySLP_SysAdmin_View_Profile.php on line 387
  • [08-Nov-2024 20:28:43 UTC] PHP Warning: Attempt to read property “blog_id” on null in /var/www/html/wp-content/plugins/myslp-customer-maintenance/include/MySLP_SysAdmin_View_Profile.php on line 387
  • [08-Nov-2024 20:28:43 UTC] PHP Warning: Undefined variable $user_blog in /var/www/html/wp-content/plugins/myslp-customer-maintenance/include/MySLP_SysAdmin_View_Profile.php on line 391
  • [08-Nov-2024 20:28:43 UTC] PHP Warning: Attempt to read property “path” on null in /var/www/html/wp-content/plugins/myslp-customer-maintenance/include/MySLP_SysAdmin_View_Profile.php on line 391
  • [08-Nov-2024 20:28:43 UTC] PHP Warning: Undefined variable $user_blog in /var/www/html/wp-content/plugins/myslp-customer-maintenance/include/MySLP_SysAdmin_View_Profile.php on line 393
  • [08-Nov-2024 20:28:43 UTC] PHP Warning: Attempt to read property “path” on null in /var/www/html/wp-content/plugins/myslp-customer-maintenance/include/MySLP_SysAdmin_View_Profile.php on line 393
  • [08-Nov-2024 20:41:38 UTC] PHP Warning: Attempt to read property “path” on int in /var/www/html/wp-content/plugins/myslp-customer-maintenance/include/MySLP_SysAdmin_View_Profile.php on line 409

Invalid submenu call

  • [08-Nov-2024 20:28:43 UTC] PHP Deprecated: strip_tags(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/wp-admin/admin-header.php on line 36

Reproduction

  • Login as SA
  • Customers | All Users
  • Search CiCi
  • Hover and click profile
  • errors are in the debug.log

Resolution

Related To Blog ID Not Set

These errors are all related to an issue in the MySLP Customer Maintenance plugin where the $user_blog var was not set to a proper WP_Site object when the user was an SA.

Added a line to fetch WP_Site based on the $myslp->User->blog_id in those cases.

Invalid Submenu Call

This strip_tags() error is coming from WP core admin functions. Turns out the admin-header rendering expected a call to add_submenu_page to actually name a menu in the first param, not pass ” as a string. Apparently you need to attach all submenus to a parent menu of some kind.


Attached the View Profile admin page to the ‘users.php’ (Customers) menu as a submenu.

ECS Cluster for Staging

Cluster Tech Eggs by ChatGPT

Store Locator Plus® is being migrated to an Elastic Container Service (ECS) cluster that is expected to be active Q4 2024. This cluster is to be automatically updated via the myslp_aws_ecs_kit git repo which triggers a CodePipeline build that deploys updates to the cluster.

ECS Cluster

The ECS cluster that is accessed by the pipeline is myslp-ecs-cluster.
arn:aws:ecs:us-east-1:744590032041:cluster/myslp-staging-cluster

This cluster is designed to run EC2 instances that host the SLP SaaS containers.

Infrastructure

The instances are managed by the following Auto Scaling Group (ASG):

Infra-ECS-Cluster-myslp-staging-cluster-a97a9fa8-ECSAutoScalingGroup-zoFBNbZvjeFk

arn:aws:autoscaling:us-east-1:744590032041:autoScalingGroup:e0255cb5-e03b-4f35-adb4-398b947028b8:autoScalingGroupName/Infra-ECS-Cluster-myslp-staging-cluster-a97a9fa8-ECSAutoScalingGroup-zoFBNbZvjeFk

This provides the compute capacity (EC2 instances here) to run the container service that defined services will use to run tasks.

Auto Scaling Group Details

Should have a minimum capacity of 1.

The group uses the following launch template: lt-07e8f4ebedbe1c2ff

That launch template runs image ID: ami-05a490ca1a643e9ea

It runs on an “gravitron compute” instance which is ARM64 compatible. Currently it runs on a c6g.xlarge.

The system tags help associate any resources launched by this ASG with the ECS cluster. The special sauce is in the launch template inline scripts, however.

Launch Template Details

The following “advanced details” in the launch template seem to be what registers any EC2 instances that this ASG fires up with the ECS Cluster:

User data contains scripts or other things that run as soon as the container comes online.

The AMI likely has AWS libraries loaded, one of which is an ECS tool that works with the AWS fabric and reads the /etc/ecs/ecs.config file to figure out how to connect a resource to the cluster on boot or on a daemon service refresh.

Tasks

These are the ECS equivalent of Docker Composer files with added information about what type of container to create.

The task definition on AWS Console for the configuration below is named slp_saas_staging:3 (as of Oct 31 2024). In addition to the environment variables noted below, an addition environment variable is added when creating the task definitions via the console to set the WORDPRESS_DB_PASSWORD environment variable. This is set for the myslp_dashboard database (baked into the ECR image that is built with CodePipeline via the WORDPRESS_DB_NAME environment variable) with a user of myslp_genesis (also per the ECR image in the WORDPRESS_DB_USER environment variable).

From the myslp_aws_ecs_kit repo AWS/ECS/tasks/slp_saas_staging.json

{
"family": "slp_saas_staging",
"requiresCompatibilities": ["EC2"],
"runtimePlatform": {
"operatingSystemFamily": "LINUX",
"cpuArchitecture": "ARM64"
},
"networkMode": "awsvpc",
"cpu": "3 vCPU",
"memory": "6 GB",
"executionRoleArn": "arn:aws:iam::744590032041:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "slp_saas",
"essential": true,
"image": "744590032041.dkr.ecr.us-east-1.amazonaws.com/myslp2024-aarch64:staging",
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
}
],
"environment" : [
{
"name" : "WP_HOSTURL",
"value" : "staging.storelocatorplus.com"
},
{
"name" : "WP_HOME",
"value" : "https://staging.storelocatorplus.com/"
},
{
"name" : "WP_SITEURL",
"value" : "https://staging.storelocatorplus.com/"
},
{
"name" : "WORDPRESS_DB_HOST",
"value" : "slp-staging-2023-aug-cluster-cluster.cluster-c0glwpjjxt7q.us-east-1.rds.amazonaws.com"
},
{
"name" : "WORDPRESS_DEBUG",
"value" : "true"
},
{
"name" : "WORDPRESS_CONFIG_EXTRA",
"value": "define( 'WP_DEBUG_LOG', '/var/www/html/debug.log');define( 'WP_DEBUG_DISPLAY', true);define( 'WP_DEBUG_SCRIPT', true);@ini_set('display_errors',1);define('SUNRISE', true);defined('DOMAIN_CURRENT_SITE') || define('DOMAIN_CURRENT_SITE', getenv_docker('WP_HOSTURL', 'staging.storelocatorplus.com') );define('WP_ALLOW_MULTISITE', true );define('MULTISITE', true);define('SUBDOMAIN_INSTALL', false);define('PATH_CURRENT_SITE', '/');define('SITE_ID_CURRENT_SITE', 1);define('BLOG_ID_CURRENT_SITE', 1);if ( ! defined( 'WPMU_PLUGIN_DIR' ) ){define('WPMU_PLUGIN_DIR', dirname( __FILE__ ) . '/wp-content/mu-plugins' );}"
}
]
}
]
}

Services

Services run various parts of the application. For SLP in the initial Q4 2024 state there is only one service – the SLP SaaS web service.

The staging service that runs the SaaS staging task is at:
arn:aws:ecs:us-east-1:744590032041:service/myslp-staging-cluster/myslp-staging-service

The service is set to run the slp_saas_staging task in daemon mode. That means it will run one task per container.

The service definition sets up the containers.
Container Image (on ECR): 744590032041.dkr.ecr.us-east-1.amazonaws.com/myslp2024-aarch64:staging

It also sets up the environment variables passed into the container.

Updating Staging SaaS Server

This process is for updating the staging Store Locator Plus® SaaS server running on an ECS cluster after performing code updates.

These processes require a locally installed copy of the MySLP AWS ECS Kit repository which can be found at ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/myslp_aws_ecs_kit.

Edit your code or deployment kit files first. This can include WordPress plugins or themes, the Docker composer or image builder commands, helper scripts, or various configuration files used to manage and deploy the Store Locator Plus® SaaS container images.

Once your updates are ready, make sure the WordPress stack is up-to-date by updating the submodule links, then commit all of your updates to the MySLP AWS ECS Kit repository on the proper branch. There are AWS CodePipeline services running that will monitor the repository for changes, build any images as needed with ECR and deploy them via the Elastic Container Service if possible. Details on the processes are noted below.

Update The Submodules

From the MySLP AWS ECS Kit git project root:

./tools/create_mustuseplugins_stubs.sh

Commit The Code Updates To The Repo

Commit any changes to the MySLP AWS ECS Kit repository.

When you push the changes from your local develop, staging, or production branch an AWS listener service will detect the code changes and run Code Pipeline tied to services such as CodeBuild and ECS to deploy the final Store Locator Plus® SaaS container in the AWS cloud.

Commits to local branches will not trigger a change in the AWS deployments.

Commits to any branch not specifically named develop, staging, or production will not trigger changes in the AWS cloud deployments.

CodePipeline Notes

The CodePipeline that is configured to deploy the staging containers is named myslp-webserver-staging-pipeline.

Stage: Source

The pipeline monitors the staging branch on the AWS CodeCommit repo for the MySLP AWS ECS Kit project at ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/myslp_aws_ecs_kit

Stage: Build

The source will be read from the URL above and a series of commands will be executed in the cloud to create an container image. This image is stored in the AWS Elastic Container Registry as a private image.

The Store Locator Plus® SaaS (internal name: MySLP) container images are stored in the 744590032041.dkr.ecr.us-east-1.amazonaws.com/myslp2024-aarch64 docker image repository.

Staging branches will tag the latest build with the :staging tag.

Stage: Deploy

The deploy stage will execute if the build stage completes successfully. This stage will attempt to take the latest myslp2024-aarch64:staging ECR image and launch an active container in the AWS Elastic Container Service.

The deploy stage will attempt to launch a running container in the myslp-staging-cluster on the myslp-staging-service service within that cluster.

Manual Container Image Update

Build The Container Image and Store On AWS ECR

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

cd ./Docker/Images

docker build --platform=linux/arm64 -t 744590032041.dkr.ecr.us-east-1.amazonaws.com/myslp2024-aarch64:staging .
docker push 744590032041.dkr.ecr.us-east-1.amazonaws.com/myslp2024-aarch64:staging

SaaS Development / ECS Error establishing a database connection

Check The Server URL

For local development using composer the Docker/Composers/Secrets/docker-compose-rds-secrets.yml file will have the DB Host URL.

For ECS deployments the URL is in the Task Definition that is being run by the service. After updating the task you will want to deploy it to the ECS Service with Force Deployment and update the running service.

Check The Port

Newer database connections are not connecting on the default MySQL Port 3306 and instead use a different port. Newer systems use port 3309 for the development database server per the RDS database setup example.

Edit the Docker/Composers/Secrets/docker-compose-rds-secrets.yml file and add the port to the end:

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.