Skip to main content

Suma Management Plugin (v1.1.0)

The core platform plugin providing site tracking, cost management, license tracking, Pinecone vectorization, reporting, and administration for all Rhino Group client sites.


Plugin Structure

suma-management/
├── suma-management.php ← Bootstrap, hooks, menu registration
├── api.php ← AJAX endpoint router (40+ actions)
├── classes/
│ ├── Base.php ← Shared utilities (DB helpers, date formatting)
│ ├── Site.php ← Site model (40+ properties, CRUD)
│ ├── Site_Update.php ← MainWP sync engine
│ ├── Sites.php ← Site list queries, filtering, export
│ ├── Costs.php ← Cost/license CRUD operations
│ ├── License.php ← License CPT management
│ ├── Pinecone.php ← Pinecone API client
│ ├── Pinecone_Sync.php ← Auto-vectorization on site update
│ ├── Pinecone_Settings.php ← Settings page for Pinecone config
│ ├── Admin.php ← Admin menus, pages, assets
│ ├── Settings.php ← General settings pages
│ ├── Search.php ← Full-text site search
│ ├── Logs.php ← Activity logging
│ ├── Reports.php ← Report generation (KoolReport)
│ ├── Lighthouse.php ← Performance audit integration
│ ├── Screenshot.php ← Headless Chrome screenshots
│ ├── Asana.php ← Asana workspace integration
│ ├── Git.php ← Bitbucket commit tracking
│ ├── Google.php ← Google Sheets/Analytics/GTM
│ ├── Cloudflare.php ← Cloudflare zone management
│ └── Envato.php ← Envato license verification
├── views/ ← Admin page templates
├── css/ ← Bootstrap + custom styles
├── js/ ← jQuery + custom scripts
└── composer.json ← Dependencies (Asana, SSL, Chrome, etc.)

Site Model

The Site class is the primary data model, representing a managed WordPress or BigCommerce site.

Key Properties (40+)

class Site {
public int $site_id;
public string $name;
public string $url;
public int $type;
public bool $ssl;
public bool $indexed;
public ?string $last_update;
public ?string $date_of_launch;
public int $plugin_count;
public string $tier;
public string $server;
public string $proxy;
public bool $debug;
public bool $ecommerce;
public string $uptime;
public string $organization;
public bool $accessibe;
public string $gtm_path;
public string $cf_zone_id;
public bool $wpcron;
public bool $h1;
public bool $readonly;
public bool $archived;
public bool $dev;
public string $platforms;
// ... additional properties
}

CRUD Operations

// Get a site by ID
$site = new Site($site_id);

// Get all active sites
$sites = Sites::get_all(['archived' => 0]);

// Update site properties
$site->update(['ssl' => 1, 'indexed' => 1]);

// Archive a site (soft-delete)
$site->archive();

Hooks

HookTypeWhen Fired
suma_site_updatedActionAfter a site sync completes
suma_site_deletedActionWhen a site is permanently deleted
suma_site_archivedActionWhen a site is archived

Site Update Engine

The Site_Update class handles synchronizing site data from MainWP and external checks.

Sync Process

1. MainWP data fetch (plugins, themes, WP version)
2. SSL certificate check (spatie/ssl-certificate)
3. Google indexing verification
4. UptimeRobot status sync
5. Plugin count calculation
6. Debug mode detection
7. WP-Cron status check
8. H1 tag verification
9. Update suma_sites record
10. Fire suma_site_updated hook

Update Queue

Sites are processed through a queue system (suma_cron table):

  • Cron adds 15 sites per execution
  • Full cycle processes all active sites in 4–6 hours
  • Queue is rebuilt when empty via sites-add-to-queue.php

Cost Management

The Costs class manages plugin/theme/service cost tracking.

Cost Types

Type IDName
1Plugin
2Theme
3Service
4Hosting
5Other

Cost-Site Assignment

// Assign cost to site
Costs::assign_to_site($cost_id, $site_id, [
'version' => '3.2.1',
'key' => 'license-key-here',
'price' => 49.00,
'active' => 1
]);

// Get all costs for a site
$site_costs = Costs::get_for_site($site_id);

// Get all sites using a cost
$sites_using = Costs::get_sites_for_cost($cost_id);

License System

Licenses are stored as a Custom Post Type (suma_license) with metadata linking them to cost records via suma_license_mapping.

License CPT Fields

  • License key
  • Vendor
  • Expiration date
  • Max activations
  • Current activations
  • Status (active, expired, revoked)

Pinecone Integration

See Pinecone Integration for detailed documentation.

Quick Summary

  • Index: rhino-tickets
  • Namespace: manage-rhinogroup
  • Model: gemini-embedding-001 (768 dimensions)
  • Auto-sync: Fires on suma_site_updated hook
  • AJAX endpoints: test_connection, sync_all, sync_site, get_stats

Reports System

The Reports class generates various management reports using KoolReport.

Available Reports

ReportDescription
RenewalsUpcoming cost renewals within 30/60/90 days
Unused EnvatoEnvato purchases not assigned to any site
All EnvatoComplete Envato license inventory
Plugin CSVExportable plugin data for all sites
ValidationData integrity checks (orphaned records)
Sites ExportFull site data CSV export
Sites with PluginFind all sites running a specific plugin
Paid InactivePaid plugins that are deactivated
Added/DeletedRecent plugin installation/removal activity
DisconnectedMainWP disconnected sites
VulnerabilityActive vulnerability summary

Admin Interface

WordPress Admin
└── Suma Management
├── Sites (list + detail views)
├── Costs (cost management)
├── Licenses
├── Reports
├── Logs
├── Search
├── Pinecone Settings
└── Settings

Frontend Stack

  • CSS: Bootstrap 5 + custom stylesheets
  • JS: jQuery + custom scripts (no build step)
  • Tables: DataTables for sortable/filterable lists
  • Charts: KoolReport for report visualizations

Composer Dependencies

{
"require": {
"asana/asana": "^0.10",
"spatie/ssl-certificate": "^1.22.1",
"chrome-php/chrome": "^0.8.1",
"google/apiclient": "^2.7",
"cloudflare/sdk": "^1.1.6",
"php-curl-class/php-curl-class": "^9.4",
"koolreport/pro": "*",
"guzzlehttp/guzzle": "^7.8"
}
}

API Router (api.php)

The AJAX endpoint router uses a switch statement pattern:

<?php
// Security checks at top
check_ajax_referer('suma_management_nonce', 'nonce');
if (!current_user_can('manage_options')) {
wp_send_json_error('Insufficient permissions');
}

$action = sanitize_text_field($_POST['action'] ?? '');

switch ($action) {
case 'get_sites':
$sites = new Sites();
wp_send_json_success($sites->get_all($_POST));
break;

case 'sync_site':
$site_update = new Site_Update(intval($_POST['site_id']));
$result = $site_update->run();
wp_send_json_success($result);
break;

case 'pinecone_sync_all':
$sync = new Pinecone_Sync();
$result = $sync->sync_all_sites();
wp_send_json_success($result);
break;

// ... 40+ more cases
}

Key WordPress Hooks

Actions Registered

// Admin menus
add_action('admin_menu', [$admin, 'register_menus']);

// Site update hooks
add_action('suma_site_updated', [Pinecone_Sync::class, 'on_site_updated']);

// AJAX handlers
add_action('wp_ajax_suma_management', [$this, 'handle_ajax']);

// Admin assets
add_action('admin_enqueue_scripts', [$admin, 'enqueue_assets']);

Filters Registered

// Modify site data before display
add_filter('suma_site_display_data', [$this, 'enhance_site_data']);