Ambrosiano Milano — In Depth Analysis
Process Dec 13, 2025 9 min read

Ambrosiano Milano — In Depth Analysis

Enterprise WordPress platform for a Milan-based precious metals trading company. Features real-time gold/silver quotations from external APIs, custom rate-limited lead generation forms with SMS notifications, and ETag-based REST API optimization achieving 95% bandwidth reduction.

Lushano Perera
Lushano Perera
Author

Project Overview

Ambrosiano Milano is a Milan-based precious metals trading company specializing in gold and silver buying/selling. The project involved developing a comprehensive WordPress-based platform that handles real-time precious metals quotations, lead generation forms with SMS notifications, B2B wholesale pricing, and landing pages optimized for conversion.

Key Business Requirements

  • Real-time quotations for gold (9K-24K) and silver (800-999) updated from external APIs
  • Dual pricing systems for retail and B2B wholesale customers
  • Lead generation forms with SMS notifications and spam protection
  • High-conversion landing pages for marketing campaigns
  • Mobile-responsive design with fast loading times
  • Italian market compliance including phone validation and GDPR considerations

Technology Stack

LayerTechnologyPurpose
CMSWordPress 6.xContent management
ServerCloudways (Nginx + PHP-FPM)Managed hosting
DatabaseMariaDB 10.6Data storage
CacheRedis + BreezeObject caching
FormsContact Form 7 + Custom ExtensionsLead capture
FieldsAdvanced Custom Fields ProFlexible content
BuildGulp 4, SASS, PostCSS, TerserAsset pipeline
JS LibrariesjQuery, Fancybox, Flickity, jQuery ValidateFrontend interactions
External APIsGoldPrice.org, DaytradingSA.ch, Esendex SMSData integration
DevelopmentDocker (MariaDB, Redis, WordPress)Local environment
Deploymentrsync over SSHServer sync

Architecture Overview

Theme Structure

ambrosiano-theme/
├── functions.php # Theme bootstrap (session init + module loading)
├── inc/ # Modular PHP functionality
│ ├── setup.php # Theme features, admin customization
│ ├── styles-scripts.php # Asset enqueuing
│ ├── acf_fields.php # ACF field definitions
│ ├── panels.php # Quotation API integration
│ ├── prospect_actions.php # Form handling, SMS, rate limiting
│ └── rest.php # Custom REST API endpoints
├── parts/ # Reusable template components
├── tp_*.php # Custom page templates (30+)
├── sass/ # SCSS source files
├── css/ # Compiled CSS
├── js/ # JavaScript (vendor + main.js)
└── gulpfile.js # Build configuration

Data Flow Architecture


Key Features Implemented

1. Real-Time Quotation System

The quotation system fetches precious metals prices from multiple external APIs and displays them to users with automatic updates.

Backend Implementation (inc/panels.php):

<?php
/**
* Fetch quotations from external APIs and store in WordPress options
* Triggered via cron job every 2 minutes
*/
add_action('ambrosiano_refresh_quotations', function() {
// Fetch gold spot prices from GoldPrice.org
$spot_response = wp_remote_get(
'https://data-asg.goldprice.org/dbXRates/EUR',
['timeout' => 30, 'httpversion' => '1.1']
);

if (!is_wp_error($spot_response)) {
$spot_data = json_decode(wp_remote_retrieve_body($spot_response), true);
$gold_spot = $spot_data['items'][0]['xauPrice'] ?? 0;
$silver_spot = $spot_data['items'][0]['xagPrice'] ?? 0;

update_option('ambrosiano_value_gold_stock', $gold_spot);
update_option('ambrosiano_value_silver_stock', $silver_spot);
}

// Fetch karat-specific quotations from DaytradingSA
$quote_response = wp_remote_get(
'https://www.daytradingsa.ch/API/getQuote.php',
['timeout' => 30]
);

if (!is_wp_error($quote_response)) {
$quotes = json_decode(wp_remote_retrieve_body($quote_response), true);

// Store individual karat prices
update_option('ambrosiano_value_gold_09', $quotes['gold_375'] ?? 0);
update_option('ambrosiano_value_gold_14', $quotes['gold_585'] ?? 0);
update_option('ambrosiano_value_gold_18', $quotes['gold_750'] ?? 0);
update_option('ambrosiano_value_gold_24', $quotes['gold_999'] ?? 0);
// ... additional prices
}

// Update timestamp
update_option('ambrosiano_last_timestamp', current_time('mysql'));

// Clear page cache
if (class_exists('Breeze_Admin')) {
do_action('breeze_clear_all_cache');
}
});

REST API with ETag Optimization (inc/rest.php):

<?php
/**
* REST endpoint with ETag-based conditional responses
* Reduces bandwidth by 95% when quotations haven't changed
*/
function ambrosiano_rest_api_check_update() {
$retail_updated = get_transient('ambrosiano_quotations_updated');
$b2b_updated = get_transient('ambrosiano_quotations_b2b_updated');

// Generate ETag from update timestamps
$etag_data = [
'retail' => $retail_updated ? (int)$retail_updated : 0,
'b2b' => $b2b_updated ? (int)$b2b_updated : 0,
];
$etag = '"' . md5(wp_json_encode($etag_data)) . '"';

// Check for If-None-Match header (client's cached ETag)
$client_etag = $_SERVER['HTTP_IF_NONE_MATCH'] ?? '';

// If ETags match, return 304 Not Modified (saves ~1.8KB per request)
if ($client_etag === $etag) {
$response = new WP_REST_Response(null, 304);
$response->header('ETag', $etag);
$response->header('X-Quotation-ETag', $etag); // Cloudways compatibility
$response->header('Cache-Control', 'no-cache, must-revalidate');
return $response;
}

// Return full data with new ETag
$data = [
'retail_updated' => $retail_updated !== false,
'b2b_updated' => $b2b_updated !== false,
'retail_timestamp' => $retail_updated ? (int)$retail_updated : null,
'b2b_timestamp' => $b2b_updated ? (int)$b2b_updated : null,
];

$response = new WP_REST_Response($data, 200);
$response->header('ETag', $etag);
$response->header('Cache-Control', 'no-cache, must-revalidate');
return $response;
}

Frontend JavaScript Polling (js/main.js):

// ETag-based polling for bandwidth optimization
var quotationCheckETag = null;

function checkQuotationUpdates() {
$.ajax({
url: ambro_site_url + '/wp-json/ambrosiano/v1/check-update',
method: 'GET',
beforeSend: function(xhr) {
// Send cached ETag for conditional request
if (quotationCheckETag) {
xhr.setRequestHeader('If-None-Match', quotationCheckETag);
}
},
statusCode: {
304: function() {
// Not Modified - quotations unchanged, no action needed
// Bandwidth saved: ~1.8KB
}
}
})
.done(function(result, textStatus, xhr) {
// Store new ETag for next request
var newETag = xhr.getResponseHeader('ETag') ||
xhr.getResponseHeader('X-Quotation-ETag');
if (newETag) {
quotationCheckETag = newETag;
}

// Update UI if quotations changed
if (result && result.retail_updated) {
refreshQuotationDisplay();
}
});
}

// Poll every 10 seconds
setInterval(checkQuotationUpdates, 10000);

2. Form Rate Limiting System

A custom anti-spam system that limits form submissions to one per phone number per 12 hours.

Database Schema:

CREATE TABLE wp_ambro_blocked_numbers (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
phone_number VARCHAR(20) NOT NULL,
form_id INT NOT NULL,
last_submission DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY form_phone (form_id, phone_number)
);

Rate Limiting Implementation (inc/prospect_actions.php):

<?php
/**
* Check if user can submit based on 12-hour cooldown
*/
function can_user_submit($phone_number, $form_id) {
global $wpdb;
$table = $wpdb->prefix . 'ambro_blocked_numbers';

$last_submission = $wpdb->get_var($wpdb->prepare(
"SELECT last_submission FROM $table
WHERE phone_number = %s AND form_id = %d",
$phone_number, $form_id
));

if ($last_submission) {
$twelve_hours_ago = time() - (12 * 3600);
return strtotime($last_submission) <= $twelve_hours_ago;
}

return true; // Phone not found, allow submission
}

/**
* CF7 validation filter - rate limiting
*/
add_filter('wpcf7_validate_text*', function($result, $tag) {
$tag = new WPCF7_Shortcode($tag);

if ($tag->name === 'your-phone') {
$phone = $_POST['your-phone'] ?? '';
$form_id = $_POST['_wpcf7'] ?? 0;

if (!empty($phone) && !can_user_submit($phone, $form_id)) {
$result->invalidate($tag,
'Hai già inviato una richiesta. Riprova tra 12 ore.');
} else {
// Record submission
global $wpdb;
$wpdb->replace(
$wpdb->prefix . 'ambro_blocked_numbers',
[
'phone_number' => sanitize_text_field($phone),
'form_id' => intval($form_id),
'last_submission' => current_time('mysql')
]
);
}
}

return $result;
}, 10, 2);

3. Italian Phone Validation

Custom regex validation for Italian mobile and landline numbers.

<?php
/**
* Custom Italian phone number validation for Contact Form 7
*/
add_filter('wpcf7_is_tel', function($result, $tel) {
// Match Italian mobile and landline formats
// Mobile: 338, 347, 366, 333, 329, 346 + 6-7 digits
// Accepts: +39, 0039, or without prefix
$result = preg_match(
'/^(\((00|\+)39\)|(00|\+)39)?(38[890]|34[7-90]|36[680]|33[3-90]|32[89]|346)\d{6,7}$/',
$tel
);
return $result;
}, 10, 2);

4. Custom Contact Form 7 Tags

Extended CF7 with custom form field tags for UTM tracking and dynamic quotation display.

<?php
/**
* Register custom CF7 form tags
*/
add_action('wpcf7_init', function() {
// UTM tracking tags
wpcf7_add_form_tag('ambrosiano_utm_source', function() {
return '<input type="hidden" name="utm_source" value="' .
esc_attr($_GET['utm_source'] ?? 'direct') . '">';
});

wpcf7_add_form_tag('ambrosiano_utm_medium', function() {
return '<input type="hidden" name="utm_medium" value="' .
esc_attr($_GET['utm_medium'] ?? 'web') . '">';
});

// Dynamic quotation display tags
wpcf7_add_form_tag('ambrosiano_value_gold_18', function() {
return number_format(get_option('ambrosiano_value_gold_18'), 2, ',', '.');
});
});

/**
* Custom mail tag for session-based quotation data
*/
add_filter('wpcf7_special_mail_tags', function($output, $name, $html) {
if ($name === 'show_session_diamond_quotation') {
if (isset($_SESSION['ambro_diamond_quotation'])) {
$output = $_SESSION['ambro_diamond_quotation'];
unset($_SESSION['ambro_diamond_quotation']); // One-time use
}
}
return $output;
}, 10, 3);

5. Secure Webhook for External Triggers

Token-authenticated endpoint with rate limiting for triggering quotation refreshes.

<?php
/**
* Secure webhook endpoint for quotation refresh
* Requires token authentication and implements rate limiting
*/
function ambrosiano_rest_webhook_trigger_refresh(WP_REST_Request $request) {
// Validate authentication token
if (!defined('AMBROSIANO_WEBHOOK_TOKEN')) {
return new WP_Error('webhook_misconfigured',
'Webhook not configured', ['status' => 500]);
}

$provided_token = $request->get_param('token')
?: ($request->get_headers()['x_webhook_token'][0] ?? null);

if (empty($provided_token)) {
return new WP_Error('missing_token',
'Authentication required', ['status' => 401]);
}

// Constant-time comparison prevents timing attacks
if (!hash_equals(AMBROSIANO_WEBHOOK_TOKEN, $provided_token)) {
error_log('Webhook: Invalid token from ' . $_SERVER['REMOTE_ADDR']);
return new WP_Error('invalid_token',
'Invalid token', ['status' => 401]);
}

// Rate limiting: 30-second cooldown
$lock = get_transient('ambrosiano_webhook_refresh_lock');
if ($lock !== false) {
return new WP_Error('rate_limit',
'Rate limit exceeded', ['status' => 429]);
}

set_transient('ambrosiano_webhook_refresh_lock', time() + 30, 30);

// Trigger refresh
do_action('ambrosiano_refresh_quotations');

return [
'success' => true,
'message' => 'Quotation refresh triggered',
'timestamp' => time()
];
}

Performance Optimizations

1. ETag-Based Conditional Requests

Problem: Frontend polling every 10 seconds transferred 2KB per request, resulting in 8.4MB/hour per user.

Solution: Implemented HTTP ETag headers with 304 Not Modified responses.

Results:

MetricBeforeAfterImprovement
Response Size (unchanged)2KB200 bytes95% reduction
Bandwidth/hour/user8.4MB420KB95% reduction
HTTP StatusAlways 200304 when cachedBetter caching

2. Quotation Caching with Transients

Problem: CPU load reached 4.7 due to excessive API calls and database queries.

Solution: Implemented transient-based caching with 2-minute refresh intervals.

Results:

MetricBeforeAfterImprovement
API Calls/hour120695% reduction
Database Queries/hour7,44090088% reduction
CPU Load Average4.71.0-1.568-79% reduction

3. Conditional Asset Loading

Contact Form 7 CSS/JS only loaded on pages that actually use forms.

<?php
// Only load CF7 assets on specific templates
if (is_page_template([
'tp_section_v1.php',
'tp_quotations.php',
'tp_contact.php',
'tp_landing.php',
])) {
wp_enqueue_style('contact-form-7');
wp_enqueue_script('contact-form-7');
}

Build System (Gulp 4)

Asset Pipeline

// gulpfile.js - Build configuration

const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const sourcemaps = require('gulp-sourcemaps');
const concat = require('gulp-concat');
const uglify = require('gulp-uglify');
const imagemin = require('gulp-imagemin');
const webp = require('gulp-webp');
const browserSync = require('browser-sync').create();

// PostCSS processors for cross-browser compatibility
const processors = [
autoprefixer,
require('postcss-pxtorem'),
require('postcss-flexibility'),
require('postcss-will-change'),
require('postcss-color-rgba-fallback'),
];

// SASS Compilation
gulp.task('SASS', function() {
return gulp.src('./sass/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass({ outputStyle: 'expanded' }).on('error', sass.logError))
.pipe(postcss(processors))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./css'));
});

// JavaScript Bundle
gulp.task('MainJs', function() {
return gulp.src([
'./js/vendor/hoverIntent.js',
'./js/vendor/jquery.validate.js',
'./js/vendor/jquery.fancybox.js',
'./js/vendor/flickity.pkgd.js',
'./js/main.js'
])
.pipe(sourcemaps.init())
.pipe(concat('main.min.js'))
.pipe(uglify())
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./js'));
});

// Image Optimization with WebP generation
gulp.task('ImageMin', function() {
return gulp.src('./img_original/*.+(png|jpg|jpeg|gif|svg)')
.pipe(imagemin([
imagemin.gifsicle({ interlaced: true }),
imagemin.jpegtran({ progressive: true }),
imagemin.optipng({ optimizationLevel: 5 }),
imagemin.svgo({ plugins: [{ removeViewBox: false }] })
]))
.pipe(gulp.dest('./img'))
.pipe(webp())
.pipe(gulp.dest('./img'));
});

// Development server with live reload
gulp.task('default', gulp.parallel('watch', 'BrowserSync'));

Development Workflow

Local Environment (Docker)

# docker-compose.yml
version: '3.8'
services:
wordpress:
image: wordpress:latest
ports: ['80:80']
volumes:
- ./:/var/www/html
environment:
WORDPRESS_DB_HOST: mariadb
WORDPRESS_DB_NAME: ambrosianomilano

mariadb:
image: mariadb:10.6
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: ambrosianomilano

redis:
image: redis:alpine
ports: ['6379:6379']

Deployment Process

# Push theme changes to production
rsync -avzP --delete \
--exclude='.git' \
--exclude='node_modules' \
--exclude='img_original' \
./wp-content/themes/ambrosiano-theme/ \
user@138.68.111.141:/path/to/public_html/wp-content/themes/ambrosiano-theme/

Project Statistics

MetricValue
Total Commits124
Commits (2024-2025)64
PHP Lines of Code~19,600
Page Templates30+
REST API Endpoints6
External API Integrations4
Custom Database Tables2
ACF Field Groups5

Key Challenges Solved

1. SMS Service Resilience

Challenge: Esendex SMS API downtime caused form submissions to hang for 5+ minutes.

Solution: Implemented quick timeout (10s) with graceful degradation – forms complete successfully regardless of SMS delivery status. Documented async queue architecture for future implementation.

2. MariaDB 10.6 Compatibility

Challenge: Database dump imports failed due to MariaDB sandbox mode comments.

Solution: Created preprocessing script that strips MariaDB-specific comments before import.

# Skip MariaDB sandbox comment on line 1
tail -n +2 dump.sql > dump-fixed.sql
docker exec -i mariadb mysql -uroot -p dbname < dump-fixed.sql

3. Cloudways ETag Header Filtering

Challenge: Nginx on Cloudways stripped standard ETag headers from responses.

Solution: Added custom X-Quotation-ETag header alongside standard ETag, with JavaScript fallback to check both headers.



Technologies & Skills Demonstrated

Backend:

  • WordPress Plugin/Theme Development
  • Custom REST API Development
  • Database Design & Optimization
  • External API Integration
  • Security (Token Auth, Rate Limiting, Input Validation)
  • Cron Jobs & Background Processing

Frontend:

  • SASS/SCSS with PostCSS
  • JavaScript (jQuery, AJAX)
  • HTTP Caching (ETag, 304 Not Modified)
  • Form Validation
  • Responsive Design

DevOps:

  • Docker Development Environment
  • SSH/rsync Deployment
  • MariaDB Administration
  • Redis Caching
  • Nginx Configuration

Tools:

  • Git Version Control
  • Gulp 4 Build System
  • BrowserSync
  • WP-CLI

Written by Lushano Perera

Digital craftsman exploring the intersection of design, technology, and human experience.