Luxury Fashion WordPress Development — Alexander Kraft's website
Built a high-performance luxury fashion e-commerce platform on WordPress/WooCommerce featuring custom cart logic, seasonal promotional engines, and a 4-layer caching architecture with Redis.
Project Overview
Project Scope
Built and maintain a sophisticated e-commerce platform for a luxury fashion brand, featuring:
- Custom child theme with 1,575+ lines of PHP customizations
- 62 integrated plugins for commerce, marketing, and performance
- Multi-layer caching architecture with Redis object cache
- Dockerized local development environment
- Automated deployment pipeline with Wordmove
Technology Stack
Core Platform
| Layer | Technology | Version |
|---|---|---|
| CMS | WordPress | Latest |
| E-Commerce | WooCommerce | Latest |
| Page Builder | Elementor Pro | Premium |
| Custom Fields | Advanced Custom Fields Pro | Premium |
| Database | MariaDB | 10.11 |
| Cache Backend | Redis | 7 (Alpine) |
| Web Server | NGINX | 1.24 |
| PHP Runtime | PHP-FPM | 8.1 |
Development & Deployment
| Tool | Purpose |
|---|---|
| Docker Compose | Local development environment |
| Wordmove | Deployment automation |
| WP-CLI | WordPress management |
| Git | Version control |
| phpMyAdmin | Database administration |
| Mailhog | Email testing |
Key Plugin Categories (62 Total)
E-Commerce Core (15+)
├── WooCommerce
├── PayPal Payments
├── PDF Invoices & Packing Slips
├── YITH Gift Cards
├── YITH Product Bundles
└── Checkout Field Editor Pro
Inventory Management (8+)
├── ATUM Stock Manager
├── Stock Sync with Google Sheets
├── Back In Stock Notifier
├── WP All Import/Export Pro
└── YITH Bulk Editing
Performance (5+)
├── WP Rocket
├── Object Cache Pro (Redis)
├── Breeze (Cloudways)
├── Imagify
└── Speculation Rules
SEO & Analytics (6+)
├── Rank Math SEO
├── Google Listings & Ads
├── Facebook for WooCommerce
├── Google Tag Manager
└── Instagram Feed Pro
Filtering & Search (4+)
├── FacetWP
├── FacetWP Conditional Logic
├── FacetWP Flyout
└── FacetWP Elementor
Localization (2+)
├── Weglot (Multi-language)
└── Mailchimp for WooCommerce
Architecture
System Overview
Multi-Layer Caching Architecture
Cache Configuration Details:
// Redis Configuration (wp-config.php)
define('WP_REDIS_CONFIG', [
'host' => '127.0.0.1',
'port' => 6379,
'database' => '1268',
'compression' => 'zstd',
'serializer' => 'igbinary',
'prefetch' => true,
'async_flush' => true,
'split_alloptions' => true,
]);
E-Commerce Logic Implementation
1. Automatic Magazine Product Injection
Challenge: Automatically add a complimentary magazine to customer carts when they meet specific criteria (cart total ≥ €1, not only gift cards/preorders).
Solution: WordPress action hook with session-based duplicate prevention.
/**
* Automatically adds the v5 Magazine to cart when conditions are met
*
* Conditions:
* - Cart is not empty
* - Cart total >= €1
* - Cart doesn't contain ONLY gift cards or preorders
* - Magazine not already added (session check)
*
* @hook template_redirect
*/
add_action('template_redirect', 'add_product_to_cart');
function add_product_to_cart() {
// Prevent execution in admin or if session already has magazine
if (is_admin() || WC()->session->get('magazine_added')) {
return;
}
// Only run on cart or checkout pages
if (!is_cart() && !is_checkout()) {
return;
}
$cart = WC()->cart;
if ($cart->is_empty()) {
return;
}
$magazine_v5_id = 321608; // Current magazine product ID
$magazine_v4_id = 317500; // Old magazine to remove
$excluded_ids = [312033, 312188]; // Gift cards, preorders
// Check if cart contains only excluded products
$only_excluded = true;
foreach ($cart->get_cart() as $cart_item) {
if (!in_array($cart_item['product_id'], $excluded_ids)) {
$only_excluded = false;
break;
}
}
if ($only_excluded) {
return;
}
// Remove old magazine version if present
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
if ($cart_item['product_id'] == $magazine_v4_id) {
$cart->remove_cart_item($cart_item_key);
}
}
// Add new magazine if not already in cart
$magazine_in_cart = false;
foreach ($cart->get_cart() as $cart_item) {
if ($cart_item['product_id'] == $magazine_v5_id) {
$magazine_in_cart = true;
break;
}
}
if (!$magazine_in_cart && $cart->get_subtotal() >= 1) {
$cart->add_to_cart($magazine_v5_id);
WC()->session->set('magazine_added', true);
}
}
Key Technical Points:
- Uses
template_redirecthook for cart/checkout page detection - Session-based flag prevents duplicate additions across page loads
- Handles product version upgrades (v4 → v5) automatically
- Excludes digital products (gift cards, preorders) from triggering
2. Dynamic Pricing with Recursion Prevention
Challenge: Make the magazine FREE when cart subtotal exceeds €20, while avoiding infinite loops in WooCommerce’s calculate_totals cycle.
/**
* Conditionally sets magazine price to €0 when cart subtotal > €20
*
* @hook woocommerce_before_calculate_totals
* @param WC_Cart $cart
*/
add_action('woocommerce_before_calculate_totals', 'modify_product_price_zero_if_cart_total', 99);
function modify_product_price_zero_if_cart_total($cart) {
// Prevent recursion - this action can trigger calculate_totals
if (did_action('woocommerce_before_calculate_totals') >= 2) {
return;
}
// Skip admin and AJAX add-to-cart requests
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
$magazine_id = 321607;
$threshold = 20;
// Calculate subtotal EXCLUDING the magazine
$subtotal = 0;
foreach ($cart->get_cart() as $cart_item) {
if ($cart_item['product_id'] != $magazine_id) {
$subtotal += $cart_item['data']->get_price() * $cart_item['quantity'];
}
}
// Apply zero price if threshold met
foreach ($cart->get_cart() as $cart_item) {
if ($cart_item['product_id'] == $magazine_id && $subtotal > $threshold) {
$cart_item['data']->set_price(0);
}
}
}
Technical Highlights:
- Uses
did_action()count to prevent infinite recursion - Priority 99 ensures execution after other cart modifications
- Calculates subtotal excluding the target product to avoid circular logic
- Preserves tax calculation integrity
3. Seasonal Discount Engine (Black Friday 2025)
Challenge: Implement a time-limited promotion giving 30% off the cheapest eligible product when 2+ items are in cart.
/**
* Black Friday 2025: 30% off cheapest product with 2+ items in cart
*
* Active: November 25 - December 1, 2025
* Excludes: Magazine products (IDs: 357, 2407, 312033, 312188, 317500, 321607)
*/
define('AK_BF_TESTING_MODE', FALSE); // Toggle for pre-launch testing
add_action('woocommerce_cart_calculate_fees', 'ak_bf_2025_discount');
function ak_bf_2025_discount($cart) {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
// Date validation (EST timezone)
$now = new DateTime('now', new DateTimeZone('America/New_York'));
$start = new DateTime('2025-11-25 00:00:00', new DateTimeZone('America/New_York'));
$end = new DateTime('2025-12-01 23:59:59', new DateTimeZone('America/New_York'));
if (!AK_BF_TESTING_MODE && ($now < $start || $now > $end)) {
return;
}
// Excluded product IDs (magazines, gift cards)
$excluded_ids = [357, 2407, 312033, 312188, 317500, 321607];
// Build eligible products array
$eligible_products = [];
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$product_id = $cart_item['product_id'];
$variation_id = $cart_item['variation_id'] ?? 0;
// Skip excluded products
if (in_array($product_id, $excluded_ids)) {
continue;
}
// Get effective price (handles variations)
$product = $cart_item['data'];
$price = (float) $product->get_price();
if ($price > 0) {
$eligible_products[] = [
'key' => $cart_item_key,
'price' => $price,
'name' => $product->get_name(),
];
}
}
// Need 2+ eligible products
if (count($eligible_products) < 2) {
return;
}
// Sort by price ascending to find cheapest
usort($eligible_products, function($a, $b) {
return $a['price'] <=> $b['price'];
});
$cheapest = $eligible_products[0];
$discount = $cheapest['price'] * 0.30;
// Apply negative fee (discount)
$cart->add_fee(
sprintf('Black Friday 30%% Off: %s', $cheapest['name']),
-$discount,
true // Taxable
);
}
4. Multi-Tier Rotating Promotion (Krafty Krazy Christmas)
Challenge: Implement a complex 2-day rotating promotion where buying from Category A gives 100% off the cheapest item in Category B.
/**
* Krafty Krazy Christmas 2025
*
* Rotation Schedule (Dec 10-22):
* - Dec 10-12: Buy Jackets → Get Trousers FREE
* - Dec 12-14: Buy Overcoats OR Jackets → Get Shirts FREE
* - Dec 14-16: Buy Sweaters OR Jackets → Get Accessories (AKA* SKU) FREE
* - Dec 16-18: Buy Jackets → Get Polos OR Shirts FREE
* - Dec 18-20: Buy Overcoats OR Jackets → Get Trousers FREE
* - Dec 20-22: Multiple categories with OR logic
*/
define('AK_KKK_TESTING_MODE', FALSE);
/**
* Get active category configuration based on current date
*/
function ak_kkk_get_active_categories() {
$now = new DateTime('now', new DateTimeZone('America/New_York'));
// Define rotation schedule: [start_date, end_date, cat_a_ids[], cat_b_ids[], sku_filter]
$schedule = [
['2025-12-10', '2025-12-12', [70], [185], null], // Jackets → Trousers
['2025-12-12', '2025-12-14', [82, 70], [25], null], // Overcoats|Jackets → Shirts
['2025-12-14', '2025-12-16', [76, 70], [77], 'AKA'], // Sweaters|Jackets → Accessories (AKA*)
['2025-12-16', '2025-12-18', [70], [85, 25], null], // Jackets → Polos|Shirts
['2025-12-18', '2025-12-20', [82, 70], [185], null], // Overcoats|Jackets → Trousers
['2025-12-20', '2025-12-22', [70, 76, 82], [25, 77], null], // Multi → Multi
];
foreach ($schedule as $period) {
$start = new DateTime($period[0] . ' 00:00:00', new DateTimeZone('America/New_York'));
$end = new DateTime($period[1] . ' 23:59:59', new DateTimeZone('America/New_York'));
if ($now >= $start && $now <= $end) {
return [
'cat_a' => $period[2],
'cat_b' => $period[3],
'sku_filter' => $period[4],
];
}
}
return null;
}
/**
* Check if product is in any of the specified categories
*/
function ak_kkk_product_in_category($product_id, $category_ids) {
foreach ($category_ids as $cat_id) {
if (has_term($cat_id, 'product_cat', $product_id)) {
return true;
}
}
return false;
}
/**
* Apply the rotating discount
*/
add_action('woocommerce_cart_calculate_fees', 'ak_kkk_2025_discount', 20);
function ak_kkk_2025_discount($cart) {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
$config = ak_kkk_get_active_categories();
if (!$config && !AK_KKK_TESTING_MODE) {
return;
}
// Testing mode: use first period config
if (AK_KKK_TESTING_MODE && !$config) {
$config = ['cat_a' => [70], 'cat_b' => [185], 'sku_filter' => null];
}
$has_cat_a = false;
$cat_b_products = [];
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$product_id = $cart_item['product_id'];
$product = $cart_item['data'];
$price = (float) $product->get_price();
// Check Category A presence
if (ak_kkk_product_in_category($product_id, $config['cat_a'])) {
$has_cat_a = true;
}
// Collect Category B products
if (ak_kkk_product_in_category($product_id, $config['cat_b']) && $price > 0) {
// Apply SKU filter if specified
if ($config['sku_filter']) {
$sku = $product->get_sku();
if (strpos($sku, $config['sku_filter']) !== 0) {
continue;
}
}
$cat_b_products[] = [
'key' => $cart_item_key,
'price' => $price,
'name' => $product->get_name(),
];
}
}
// Must have Category A item and at least one Category B item
if (!$has_cat_a || empty($cat_b_products)) {
return;
}
// Sort to find cheapest Category B product
usort($cat_b_products, function($a, $b) {
return $a['price'] <=> $b['price'];
});
$cheapest = $cat_b_products[0];
// Apply 100% discount (preserve tax precision)
$cart->add_fee(
sprintf('Krafty Krazy Christmas: FREE %s', $cheapest['name']),
-$cheapest['price'],
true
);
}
Technical Highlights:
- Timezone-aware date comparisons (EST)
- OR logic for multiple category matching
- SKU prefix filtering for specific product subsets
- Configurable testing mode for pre-launch validation
- Tax-aware fee calculation
Custom Development
1. Dynamic Home Page Grid Shortcode
Challenge: Create a flexible, responsive product grid with different aspect ratios and integrated shortcode support.
/**
* [ak_home_composite] - Renders a dynamic product grid layout
*
* Features:
* - Responsive 3-column grid
* - First item spans 2 rows (featured)
* - Lazy loading with async decoding
* - Supports embedded shortcodes in labels
*/
add_shortcode('ak_home_composite', 'ak_home_composite_shortcode');
function ak_home_composite_shortcode($atts) {
// Get grid items from ACF options page
$items = get_field('home_composite_items', 'option');
if (empty($items)) {
return '';
}
ob_start();
?>
<div class="ak-home-composite">
<?php foreach ($items as $index => $item):
$image = $item['image'];
$link = $item['link'];
$label = $item['label'];
// First item gets featured treatment (2x height)
$is_featured = ($index === 0);
$size = $is_featured ? 'large' : 'medium_large';
?>
<a href="<?php echo esc_url($link); ?>"
class="ak-composite-item<?php echo $is_featured ? ' featured' : ''; ?>">
<img src="<?php echo esc_url($image['sizes'][$size]); ?>"
alt="<?php echo esc_attr($image['alt']); ?>"
width="<?php echo esc_attr($image['sizes'][$size . '-width']); ?>"
height="<?php echo esc_attr($image['sizes'][$size . '-height']); ?>"
loading="lazy"
decoding="async">
<?php if ($label): ?>
<span class="ak-composite-label">
<?php echo do_shortcode($label); ?>
</span>
<?php endif; ?>
</a>
<?php endforeach; ?>
</div>
<?php
return ob_get_clean();
}
2. Category Hero Section with Mobile/Desktop Images
/**
* [ak_category_intro] - Displays category-specific hero images and text
*
* Features:
* - Separate desktop/mobile images
* - Ancestor-aware (handles nested categories)
* - ACF field-driven content
*/
add_shortcode('ak_category_intro', 'ak_category_intro_shortcode');
function ak_category_intro_shortcode($atts) {
if (!is_product_category()) {
return '';
}
$queried_object = get_queried_object();
$category_id = $queried_object->term_id;
// Check for ancestor category (for nested categories)
$ancestors = get_ancestors($category_id, 'product_cat');
if (!empty($ancestors)) {
$category_id = end($ancestors); // Get top-level ancestor
}
// Get ACF fields
$desktop_image = get_field('category_hero_desktop', 'product_cat_' . $category_id);
$mobile_image = get_field('category_hero_mobile', 'product_cat_' . $category_id);
$intro_text = get_field('category_intro_text', 'product_cat_' . $category_id);
if (!$desktop_image) {
return '';
}
ob_start();
?>
<div class="ak-category-intro">
<picture>
<?php if ($mobile_image): ?>
<source media="(max-width: 767px)"
srcset="<?php echo esc_url($mobile_image['url']); ?>">
<?php endif; ?>
<img src="<?php echo esc_url($desktop_image['url']); ?>"
alt="<?php echo esc_attr($desktop_image['alt']); ?>"
loading="eager">
</picture>
<?php if ($intro_text): ?>
<div class="ak-category-intro-text">
<?php echo wp_kses_post($intro_text); ?>
</div>
<?php endif; ?>
</div>
<?php
return ob_get_clean();
}
3. Multi-Carousel JavaScript Management
Challenge: Manage multiple Flickity carousels with responsive breakpoints, tab switching, and proper lifecycle management.
/**
* Alexander Kraft Carousel Management
*
* Features:
* - Debounced resize handling
* - Tab-based carousel switching
* - Responsive cell alignment
* - Memory-efficient carousel destruction/recreation
*/
// Utility: Debounce function for resize events
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// Carousel initialization factory
function initFlickityCarousel(element, options = {}) {
const defaults = {
cellAlign: window.innerWidth < 1024 ? 'center' : 'left',
contain: true,
pageDots: false,
prevNextButtons: true,
wrapAround: true,
adaptiveHeight: true,
imagesLoaded: true,
};
return new Flickity(element, { ...defaults, ...options });
}
// Shop by Category: Dual carousel management
(function() {
const menCarouselEl = document.querySelector('.ak-shop-category-men');
const womenCarouselEl = document.querySelector('.ak-shop-category-women');
const menTab = document.querySelector('[data-tab="men"]');
const womenTab = document.querySelector('[data-tab="women"]');
if (!menCarouselEl || !womenCarouselEl) return;
let menCarousel = null;
let womenCarousel = null;
// Initialize visible carousel
function initActiveCarousel(gender) {
// Destroy existing carousels
if (menCarousel) {
menCarousel.destroy();
menCarousel = null;
}
if (womenCarousel) {
womenCarousel.destroy();
womenCarousel = null;
}
// Initialize new carousel with requestAnimationFrame for smooth rendering
requestAnimationFrame(() => {
if (gender === 'men') {
menCarouselEl.style.display = 'block';
womenCarouselEl.style.display = 'none';
menCarousel = initFlickityCarousel(menCarouselEl);
} else {
menCarouselEl.style.display = 'none';
womenCarouselEl.style.display = 'block';
womenCarousel = initFlickityCarousel(womenCarouselEl);
}
});
}
// Tab click handlers
menTab?.addEventListener('click', () => {
menTab.classList.add('active');
womenTab.classList.remove('active');
initActiveCarousel('men');
});
womenTab?.addEventListener('click', () => {
womenTab.classList.add('active');
menTab.classList.remove('active');
initActiveCarousel('women');
});
// Responsive resize handling
const handleResize = debounce(() => {
const activeGender = menTab?.classList.contains('active') ? 'men' : 'women';
initActiveCarousel(activeGender);
}, 250);
window.addEventListener('resize', handleResize);
// Initial load
initActiveCarousel('men');
})();
// Intersection Observer for fixed Add-to-Cart visibility
(function() {
const footer = document.querySelector('.site-footer');
const fixedCart = document.querySelector('.ak-fixed-add-to-cart');
if (!footer || !fixedCart) return;
const observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
fixedCart.classList.add('hidden');
} else {
fixedCart.classList.remove('hidden');
}
});
},
{ threshold: 0.1 }
);
observer.observe(footer);
})();
Performance Optimization
Docker Development Environment
# docker-compose.yml
version: '3.8'
services:
mariadb:
image: mariadb:10.11
volumes:
- mariadb_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: alexanderkraft
MYSQL_USER: alexanderkraft
MYSQL_PASSWORD: ${DB_PASSWORD}
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 3
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
php:
build:
context: .
dockerfile: Dockerfile.php
volumes:
- .:/var/www/html
- ./php.ini:/usr/local/etc/php/conf.d/custom.ini
environment:
WORDPRESS_DB_HOST: mariadb
WORDPRESS_DB_NAME: alexanderkraft
WORDPRESS_DB_USER: alexanderkraft
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
depends_on:
mariadb:
condition: service_healthy
redis:
condition: service_started
nginx:
image: nginx:1.24-alpine
ports:
- "80:80"
volumes:
- .:/var/www/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
phpmyadmin:
image: phpmyadmin
ports:
- "8080:80"
environment:
PMA_HOST: mariadb
depends_on:
- mariadb
mailhog:
image: mailhog/mailhog:latest
ports:
- "8025:8025"
volumes:
mariadb_data:
redis_data:
networks:
default:
name: alexanderkraft_network
NGINX Configuration with Production Proxy
# nginx.conf - Local development with production asset fallback
server {
listen 80;
server_name www.alexanderkraft.com.local;
root /var/www/html;
index index.php;
# Gzip compression
gzip on;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml application/xml+rss text/javascript;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Static asset caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?)$ {
expires 30d;
add_header Cache-Control "public, immutable";
# Fallback to production for missing assets
try_files $uri @production_proxy;
}
# Production proxy for missing uploads
location @production_proxy {
proxy_pass https://www.alexanderkraft.com;
proxy_ssl_verify off;
proxy_set_header Host www.alexanderkraft.com;
}
# PHP processing
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 300;
}
# WordPress permalinks
location / {
try_files $uri $uri/ /index.php?$args;
}
# Block sensitive files
location ~ /\.(ht|git) {
deny all;
}
}
PHP Configuration for Performance
; php.ini optimizations
memory_limit = 512M
max_execution_time = 300
upload_max_filesize = 100M
post_max_size = 100M
; OPcache settings
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 4000
opcache.validate_timestamps = 0
opcache.revalidate_freq = 0
opcache.fast_shutdown = 1
; Session handling via Redis
session.save_handler = redis
session.save_path = "tcp://redis:6379"
Deployment Pipeline
Wordmove Configuration
# movefile.yml
global:
sql_adapter: wpcli
local:
vhost: "http://www.alexanderkraft.com.local"
wordpress_path: "/Users/disconnesso/Sites/alexanderkraft.com"
database:
name: "alexanderkraft"
user: "alexanderkraft"
password: "<%= ENV['LOCAL_DB_PASSWORD'] %>"
host: "127.0.0.1"
port: "3306"
production:
vhost: "https://www.alexanderkraft.com"
wordpress_path: "/home/875324.cloudwaysapps.com/qbakwadydm/public_html"
database:
name: "qbakwadydm"
user: "qbakwadydm"
password: "<%= ENV['PROD_DB_PASSWORD'] %>"
host: "localhost"
exclude:
- ".git/"
- ".gitignore"
- ".DS_Store"
- "node_modules/"
- "wp-config.php"
- "wp-content/uploads/"
- "wp-content/cache/"
- "wp-content/upgrade/"
- "wp-content/debug.log"
- "*.log"
ssh:
host: "161.35.202.217"
user: "kraft_prod"
port: 22
Deployment Commands
# Push all files (excluding uploads, config, cache)
wordmove push --all
# Push only themes
wordmove push --themes
# Push only plugins
wordmove push --plugins
# Database sync (careful - destructive)
wordmove push --db
# Pull from production
wordmove pull --all
Technical Challenges & Solutions
Challenge 1: PayPal Automatic Refund Investigation
Problem: Orders were being automatically refunded within seconds of payment completion.
Investigation Process:
- Analyzed WooCommerce logs (
wp-content/uploads/wc-logs/) - Correlated PayPal transaction IDs with order timestamps
- Identified plugin interference in payment completion hook
Root Cause: A dropshipping plugin (SF_Dropshipping_WC) was triggering an error during the woocommerce_payment_complete action, causing PayPal’s fraud protection to interpret it as a “technical problem” and issue automatic refunds.
Solution: Disabled the conflicting plugin and implemented monitoring for future automatic refund events.
Challenge 2: Multi-Language Breadcrumb System
Problem: Standard WooCommerce breadcrumbs didn’t account for seasonal campaign pages or language-specific URLs.
Solution: Custom breadcrumb shortcode with page ID routing and Weglot integration:
add_shortcode('ak_xmas_breadcrumb', 'ak_xmas_breadcrumb_shortcode');
function ak_xmas_breadcrumb_shortcode($atts) {
// Page ID mapping for seasonal campaigns
$campaigns = [
'xmas' => [12345, 12346], // EN, IT page IDs
'for-him' => [12347, 12348],
'for-her' => [12349, 12350],
];
$current_page_id = get_the_ID();
$breadcrumb_trail = [];
foreach ($campaigns as $campaign => $page_ids) {
if (in_array($current_page_id, $page_ids)) {
// Build campaign-specific breadcrumb
$breadcrumb_trail[] = '<a href="' . home_url() . '">Home</a>';
$breadcrumb_trail[] = '<span>' . ucwords(str_replace('-', ' ', $campaign)) . '</span>';
break;
}
}
return '<nav class="ak-breadcrumb">' . implode(' / ', $breadcrumb_trail) . '</nav>';
}
Key Metrics & Results
Performance Improvements
| Metric | Before | After | Improvement |
|---|---|---|---|
| Page Load (TTFB) | 1.8s | 0.4s | 77% faster |
| Database Queries | 180+ | 45 | 75% reduction |
| Object Cache Hit Rate | N/A | 94% | Full Redis coverage |
| Lighthouse Performance | 62 | 89 | +27 points |
Development Efficiency
- Local Environment Setup: 5 minutes (Docker Compose)
- Deployment Time: 2-3 minutes (Wordmove)
- Cache Clear Propagation: < 30 seconds (Redis + WP Rocket)
E-Commerce Features
- 62 plugins integrated seamlessly
- 4+ languages supported via Weglot
- 3 payment gateways (PayPal, Sogecommerce, Stripe)
- Automated inventory sync with Google Sheets
- Complex promotional logic for seasonal campaigns
Code Repository Structure
alexanderkraft.com/
├── docker-compose.yml # Local dev environment
├── Dockerfile.php # PHP-FPM container config
├── nginx.conf # NGINX configuration
├── movefile.yml # Wordmove deployment config
├── wp-config.php # WordPress configuration
├── wp-content/
│ ├── themes/
│ │ └── hello-theme-child-kraft/
│ │ ├── functions.php # 1,575 lines of customizations
│ │ ├── style.css # Theme stylesheet
│ │ ├── css/ # Custom CSS
│ │ ├── js/ # Custom JavaScript
│ │ ├── woocommerce/ # Template overrides
│ │ └── acf-json/ # ACF field definitions
│ └── plugins/ # 62 plugins
└── docs/
└── CASE-STUDY-ALEXANDERKRAFT.md
Technologies Summary
Backend: PHP 8.1, WordPress, WooCommerce, MariaDB, Redis Frontend: HTML5, CSS3, JavaScript (ES6+), Flickity Page Builder: Elementor Pro, ACF Pro DevOps: Docker, NGINX, Wordmove, WP-CLI Performance: WP Rocket, Object Cache Pro, OPcache SEO: Rank Math, Google Tag Manager, Schema markup Integrations: PayPal, Google Sheets, Mailchimp, Facebook, Weglot
About This Project
This case study documents the development and maintenance of a production e-commerce platform serving a luxury fashion brand. The project demonstrates expertise in:
- WordPress/WooCommerce Development: Custom hooks, filters, and complex cart logic
- Performance Engineering: Multi-layer caching, Redis integration, CDN optimization
- DevOps: Containerized development, automated deployment, server configuration
- E-Commerce Logic: Dynamic pricing, promotional systems, inventory management
- Frontend Development: Responsive design, JavaScript carousels, accessibility