Skip to main content

Development Setup

Guide for setting up a local development environment for Blocker Outdoors WordPress + BigCommerce site.

System Requirements

Minimum Requirements

  • Operating System: Windows 10/11, macOS 12+, or Ubuntu 20.04+
  • PHP: 8.1 or higher (8.2 recommended)
  • MySQL: 5.7+ or MariaDB 10.6+
  • Node.js: 20.x LTS
  • npm: 10.x or higher
  • Composer: 2.x
  • Git: 2.x

PHP Extensions Required

# Check installed extensions
php -m | grep -E 'curl|gd|json|mbstring|mysqli|xml|zip|imagick|redis'

# Required extensions:
- curl
- gd or imagick
- json
- mbstring
- mysqli
- xml
- zip
- redis (optional but recommended)

Local Environment Options

Choose one of these local development environments:

Advantages: Zero-config, fast, integrated Valet-style routing

# Install Laravel Herd
# Download from: https://herd.laravel.com/

# After installation, add site
herd link blockeroutdoors

# Site will be available at:
# https://blockeroutdoors.test

Configuration:

  • PHP 8.2 (switchable via UI)
  • MySQL 8.0
  • Redis 7.x
  • Nginx

Option 2: Local by Flywheel

Advantages: GUI-based, easy site management, shareable URLs

# Install Local
# Download from: https://localwp.com/

# Create new site:
# Site Name: blockeroutdoors
# PHP: 8.2
# Web Server: Nginx
# Database: MySQL 8.0

Option 3: Docker (Cross-platform)

Advantages: Consistent environment, production parity

docker-compose.yml:

version: '3.8'

services:
wordpress:
image: wordpress:6.7.1-php8.2-apache
container_name: blocker_wordpress
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: blocker_db
WORDPRESS_DB_USER: blocker_user
WORDPRESS_DB_PASSWORD: blocker_pass
WORDPRESS_DEBUG: 1
WORDPRESS_CONFIG_EXTRA: |
define('WP_MEMORY_LIMIT', '512M');
define('WP_MAX_MEMORY_LIMIT', '512M');
volumes:
- ./wordpress:/var/www/html
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
depends_on:
- db
- redis

db:
image: mysql:8.0
container_name: blocker_mysql
environment:
MYSQL_DATABASE: blocker_db
MYSQL_USER: blocker_user
MYSQL_PASSWORD: blocker_pass
MYSQL_ROOT_PASSWORD: root_pass
volumes:
- db_data:/var/lib/mysql
ports:
- "3306:3306"

redis:
image: redis:7-alpine
container_name: blocker_redis
ports:
- "6379:6379"

phpmyadmin:
image: phpmyadmin:latest
container_name: blocker_phpmyadmin
ports:
- "8081:80"
environment:
PMA_HOST: db
PMA_USER: root
PMA_PASSWORD: root_pass

volumes:
db_data:

uploads.ini:

file_uploads = On
memory_limit = 512M
upload_max_filesize = 128M
post_max_size = 128M
max_execution_time = 600

Start environment:

docker compose up -d

# Site available at: http://localhost:8080
# phpMyAdmin at: http://localhost:8081

Initial Setup

1. Clone Repository

# Create project directory
mkdir -p ~/Sites/blockeroutdoors
cd ~/Sites/blockeroutdoors

# Clone WordPress installation (if using version control)
git clone [email protected]:rhino-group/blockeroutdoors.git .

# Or download fresh WordPress
wp core download --locale=en_US

2. Database Setup

# Create database
wp db create

# Or via MySQL CLI:
mysql -u root -p
CREATE DATABASE blocker_local CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'blocker_user'@'localhost' IDENTIFIED BY 'blocker_pass';
GRANT ALL PRIVILEGES ON blocker_local.* TO 'blocker_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

3. WordPress Configuration

wp-config.php:

<?php
/**
* WordPress Configuration - Local Development
*/

// Database settings
define( 'DB_NAME', 'blocker_local' );
define( 'DB_USER', 'blocker_user' );
define( 'DB_PASSWORD', 'blocker_pass' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', 'utf8mb4_unicode_ci' );

// Authentication keys (generate at: https://api.wordpress.org/secret-key/1.1/salt/)
define( 'AUTH_KEY', 'put your unique phrase here' );
define( 'SECURE_AUTH_KEY', 'put your unique phrase here' );
define( 'LOGGED_IN_KEY', 'put your unique phrase here' );
define( 'NONCE_KEY', 'put your unique phrase here' );
define( 'AUTH_SALT', 'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT', 'put your unique phrase here' );
define( 'NONCE_SALT', 'put your unique phrase here' );

// WordPress table prefix
$table_prefix = 'wp_';

// Development settings
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'SCRIPT_DEBUG', true );
define( 'SAVEQUERIES', true );

// Memory limits
define( 'WP_MEMORY_LIMIT', '512M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );

// Site URLs
define( 'WP_HOME', 'https://blockeroutdoors.test' );
define( 'WP_SITEURL', 'https://blockeroutdoors.test' );

// BigCommerce API credentials (test store)
define( 'BIGCOMMERCE_CLIENT_ID', 'test_client_id_here' );
define( 'BIGCOMMERCE_CLIENT_SECRET', 'test_client_secret_here' );
define( 'BIGCOMMERCE_ACCESS_TOKEN', 'test_access_token_here' );
define( 'BIGCOMMERCE_CHANNEL_ID', 123456 ); // Test channel ID
define( 'BIGCOMMERCE_STORE_URL', 'https://store-test123.mybigcommerce.com' );

// BigCommerce import settings
define( 'BIGCOMMERCE_IMPORT_BATCH_SIZE', 25 ); // Smaller batch for local
define( 'BIGCOMMERCE_CACHE_TTL', 600 ); // 10 minutes

// Suma fork settings
define( 'SUMA_BC_ENABLE_MSF', true );
define( 'SUMA_BC_PRICING_NONCE_BYPASS', false ); // Enable nonce for local testing

// Klaviyo (test account)
define( 'KLAVIYO_API_KEY', 'pk_test_xxxxx' );
define( 'KLAVIYO_PRIVATE_KEY', 'test_private_key' );
define( 'KLAVIYO_COMPANY_ID', 'TEST123' );

// Algolia (test index)
define( 'ALGOLIA_APP_ID', 'TESTAPP123' );
define( 'ALGOLIA_SEARCH_KEY', 'test_search_key' );
define( 'ALGOLIA_ADMIN_KEY', 'test_admin_key' );

// BazaarVoice (staging)
define( 'BAZAARVOICE_CLIENT_NAME', 'blockeroutdoors-staging' );
define( 'BAZAARVOICE_SITE_ID', 'main_site' );
define( 'BAZAARVOICE_ENVIRONMENT', 'staging' );

// Disable cron (use manual cron during dev)
define( 'DISABLE_WP_CRON', true );

// Redis object cache (if available)
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_DATABASE', 0 );
define( 'WP_REDIS_TIMEOUT', 1 );

// File system method
define( 'FS_METHOD', 'direct' );

// Absolute path to WordPress directory
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}

// WordPress setup
require_once ABSPATH . 'wp-settings.php';

4. Install WordPress

# Via WP-CLI (recommended)
wp core install \
--url="https://blockeroutdoors.test" \
--title="Blocker Outdoors - Local" \
--admin_user="admin" \
--admin_password="admin123" \
--admin_email="[email protected]"

# Or via browser:
# Visit https://blockeroutdoors.test/wp-admin/install.php

5. Install Plugins

# Core plugins
wp plugin install advanced-custom-fields-pro --activate
wp plugin install elementor-pro --activate

# BigCommerce for WordPress (Suma fork)
wp plugin install /path/to/bigcommerce-suma-v5.0.7.17.zip --activate

# Suma plugins
wp plugin install /path/to/suma-patches-v1.5.19.zip --activate
wp plugin install /path/to/suma-dealer-locator-v3.0.2.zip --activate
wp plugin install /path/to/suma-analytics-master-v1.3.5.zip --activate
wp plugin install /path/to/suma-bazaarvoice-integrator-v1.1.4.zip --activate
wp plugin install /path/to/back-in-stock-notifications-v1.3.2.zip --activate
wp plugin install /path/to/gift-certificate-creator-v1.0.0.zip --activate
wp plugin install /path/to/narvar-middleware-v1.2.7.zip --activate

# Search & filtering
wp plugin install facetwp-pro-v4.3.5.zip --activate
wp plugin install wp-search-with-algolia-v2.8.2.zip --activate

# Other plugins
wp plugin install duracelltomi-google-tag-manager --activate
wp plugin install gravity-forms --activate
wp plugin install wp-mail-smtp --activate

# Development tools
wp plugin install query-monitor --activate
wp plugin install debug-bar --activate

6. Install & Activate Theme

# Install Suma Elementor theme
wp theme install /path/to/suma-elementor-v3.0.0.zip

# Activate theme
wp theme activate suma-elementor

# Install dependencies
cd wp-content/themes/suma-elementor
composer install --no-dev
npm install

7. Import Database (Optional)

If you have a production database export:

# Import database
wp db import production-export.sql

# Update URLs
wp search-replace 'https://blockeroutdoors.com' 'https://blockeroutdoors.test' --all-tables

# Flush cache
wp cache flush
wp rewrite flush

Theme Development

Build Assets

cd wp-content/themes/suma-elementor

# Install dependencies
npm install

# Development build (watch mode)
npm run dev

# Production build
npm run production

# Watch for changes and rebuild
npm run watch

# Hot module replacement (with BrowserSync)
npm run hot

Asset Structure

assets/
├── src/ # Source files
│ ├── js/
│ │ ├── app.js # Main entry point
│ │ ├── components/ # Preact components
│ │ └── modules/ # JavaScript modules
│ ├── scss/
│ │ ├── app.scss # Main stylesheet
│ │ ├── base/ # Base styles
│ │ ├── components/ # Component styles
│ │ └── utilities/ # Utility classes
│ └── images/

└── dist/ # Compiled assets (gitignored)
├── css/
│ └── app.css
├── js/
│ ├── app.js
│ └── vendor.js
└── mix-manifest.json

Elementor Widget Development

Create new widget:

# Create widget file
cd wp-content/themes/suma-elementor/elementor/widgets
touch custom-widget.php

custom-widget.php:

<?php
namespace Suma_Elementor\Widgets;

use Elementor\Widget_Base;
use Elementor\Controls_Manager;

class Custom_Widget extends Widget_Base {

public function get_name() {
return 'suma_custom_widget';
}

public function get_title() {
return __( 'Custom Widget', 'suma-elementor' );
}

public function get_icon() {
return 'eicon-code';
}

public function get_categories() {
return [ 'suma-custom' ];
}

protected function register_controls() {
// Add controls here
}

protected function render() {
$settings = $this->get_settings_for_display();
// Output widget HTML
}
}

Register widget in functions.php:

add_action( 'elementor/widgets/register', function( $widgets_manager ) {
require_once get_template_directory() . '/elementor/widgets/custom-widget.php';
$widgets_manager->register( new \Suma_Elementor\Widgets\Custom_Widget() );
} );

BigCommerce Development

Connect Test Store

  1. Create test store at https://www.bigcommerce.com/essentials/free-trial/
  2. Set up API credentials (see BigCommerce Integration)
  3. Create channel for local site
  4. Add credentials to wp-config.php

Import Test Products

# Import sample products
wp bigcommerce import products --all --verbose

# Import specific category
wp bigcommerce import products --category=123

# Check import status
wp bigcommerce queue-status

Test Webhooks Locally

Use ngrok to expose local site for webhook testing:

# Install ngrok
# Download from: https://ngrok.com/download

# Start tunnel
ngrok http https://blockeroutdoors.test:443

# Copy HTTPS URL (e.g., https://abc123.ngrok.io)

# Update BigCommerce webhook URLs:
wp bigcommerce webhooks-register --force --url=https://abc123.ngrok.io

Database Management

Export Database

# Full export
wp db export blocker_local_backup.sql

# Structure only
wp db export --tables=$(wp db tables --format=csv) --no-data blocker_structure.sql

# Specific tables
wp db export --tables=wp_posts,wp_postmeta blocker_posts_backup.sql

Search & Replace

# Dry run (preview changes)
wp search-replace 'old-url.com' 'new-url.com' --dry-run

# Execute replacement
wp search-replace 'https://blockeroutdoors.com' 'https://blockeroutdoors.test' --all-tables

# Skip specific tables
wp search-replace 'old' 'new' --skip-tables=wp_options

Debugging

Enable Debug Logging

Already enabled in wp-config.php above. View logs:

# Tail debug log
tail -f wp-content/debug.log

# View last 100 lines
tail -n 100 wp-content/debug.log

# Search for errors
grep "PHP Fatal error" wp-content/debug.log

Query Monitor

Installed as development plugin. Access via admin bar:

  • Queries: View all database queries with timing
  • Hooks: See fired hooks and actions
  • HTTP: Monitor API requests
  • PHP Errors: Display PHP warnings/notices
  • Template: View loaded template files

Xdebug Setup

php.ini configuration:

[xdebug]
zend_extension=xdebug.so
xdebug.mode=debug,develop
xdebug.start_with_request=yes
xdebug.client_host=127.0.0.1
xdebug.client_port=9003
xdebug.log=/tmp/xdebug.log

VS Code launch.json:

{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "${workspaceFolder}",
"/Users/username/Sites/blockeroutdoors": "${workspaceFolder}"
}
}
]
}

Testing

Unit Tests (PHPUnit)

# Install PHPUnit
composer require --dev phpunit/phpunit

# Install WordPress test library
bash bin/install-wp-tests.sh blocker_test root '' localhost latest

# Run tests
./vendor/bin/phpunit

# Run specific test
./vendor/bin/phpunit tests/test-custom-plugin.php

Browser Testing

# Install Playwright
npm install -D @playwright/test

# Run tests
npx playwright test

# Run with UI
npx playwright test --ui

# Generate test
npx playwright codegen https://blockeroutdoors.test

Deployment

Production Deployment Checklist

  1. Build production assets

    npm run production
  2. Flush caches

    wp cache flush
    wp transient delete --all
  3. Export database

    wp db export production-$(date +%Y%m%d).sql
  4. Update wp-config.php

    • Set WP_DEBUG to false
    • Update BigCommerce credentials to production
    • Update Klaviyo/Algolia/BazaarVoice to production
  5. Deploy files via SFTP/Git

  6. Import database (if needed)

    wp db import production-backup.sql
    wp search-replace 'blockeroutdoors.test' 'blockeroutdoors.com' --all-tables
  7. Reindex search

    wp facetwp index
    wp algolia reindex products --clear
  8. Clear production cache

    • Cloudflare: Purge everything
    • WP Rocket: Clear cache
    • Redis: wp cache flush

Troubleshooting

Common Issues

Port Conflicts

# Check what's using port 80
sudo lsof -i :80

# Check what's using port 3306
sudo lsof -i :3306

PHP Memory Errors

Increase memory in php.ini:

memory_limit = 512M

Permissions Errors

# Fix WordPress file permissions
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;

# Make uploads writable
chmod -R 775 wp-content/uploads

Database Connection Errors

# Test MySQL connection
mysql -u blocker_user -p -h localhost blocker_local

# Check MySQL is running
sudo systemctl status mysql
# or
brew services list | grep mysql

Useful Commands

# Clear all caches
wp cache flush && wp transient delete --all && wp rewrite flush

# Regenerate thumbnails
wp media regenerate --yes

# Update WordPress core
wp core update

# Update all plugins
wp plugin update --all

# List installed plugins
wp plugin list

# Check plugin updates
wp plugin list --update=available

# Optimize database
wp db optimize

# Repair database
wp db repair

Additional Resources