Skip to main content

Data Sovereignty Principle

Both the plugin and theme own all their data in custom database tables. This is a fundamental architectural decision.

Why Custom Tables?

  • Performance — Optimized schema, proper indexes, no EAV overhead
  • Independence — No dependency on WordPress options table
  • Scalability — Can handle thousands of products/orders efficiently
  • Clean separation — Plugin data and theme data don't interfere

Plugin Data Access

Configuration

// Store plugin settings
wpec_set_option('store_name', 'My Store', 'general');
wpec_get_option('store_name', 'Default Store');

// NEVER do this:
update_option('wpec_store_name', 'My Store'); // WRONG!
get_option('wpec_store_name'); // WRONG!

Cache

// Plugin cache (custom ec_cache table)
wpec_cache_set('product_count', 150, 3600); // TTL in seconds
$count = wpec_cache_get('product_count');

// NEVER do this:
set_transient('wpec_product_count', 150, 3600); // WRONG!

Theme Data Access

Configuration

// Store theme settings
flavor_set_option('header_sticky', 'true', 'header');
flavor_get_option('header_sticky', 'false');

// NEVER do this:
get_option('flavor_options'); // WRONG! The blob was deleted in v3.2.5
update_option('flavor_header_sticky', 'true'); // WRONG!

Cache

// Theme cache (custom flavor_cache table)
flavor_cache_set('menu_html', $html, 1800);
$html = flavor_cache_get('menu_html');

// IMPORTANT: flavor_cache_get() returns null (not false)
$val = flavor_cache_get('counter');
if ($val !== null) { /* exists */ }

// For integer casts with default:
$count = (int) flavor_cache_get('counter', 0);

// NEVER do this:
set_transient('flavor_menu_html', $html, 1800); // WRONG!

Module Settings

Module settings use dedicated option keys:

// Correct — dedicated key per module
flavor_set_option('wishlist_enabled', 'true', 'flavor_module_wishlist');
flavor_get_option('wishlist_enabled', 'false', 'flavor_module_wishlist');

// Wrong — shared options blob
flavor_set_option('wishlist_enabled', 'true'); // Don't pollute default group

WordPress Data (Read-Only)

For data that belongs to WordPress, use standard functions:

// These are fine — reading WordPress-owned data
get_option('admin_email');
get_option('date_format');
get_option('permalink_structure');

Type Safety

flavor_get_option() has built-in type safety:

// If caller passes array default but DB stores a scalar,
// it returns the default array (prevents crashes)
$colors = flavor_get_option('brand_colors', ['#000', '#fff']);
// If DB has scalar string → returns ['#000', '#fff']
// If DB has proper JSON array → returns parsed array