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
| Hook | Type | When Fired |
|---|---|---|
suma_site_updated | Action | After a site sync completes |
suma_site_deleted | Action | When a site is permanently deleted |
suma_site_archived | Action | When 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 ID | Name |
|---|---|
| 1 | Plugin |
| 2 | Theme |
| 3 | Service |
| 4 | Hosting |
| 5 | Other |
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_updatedhook - AJAX endpoints: test_connection, sync_all, sync_site, get_stats
Reports System
The Reports class generates various management reports using KoolReport.
Available Reports
| Report | Description |
|---|---|
| Renewals | Upcoming cost renewals within 30/60/90 days |
| Unused Envato | Envato purchases not assigned to any site |
| All Envato | Complete Envato license inventory |
| Plugin CSV | Exportable plugin data for all sites |
| Validation | Data integrity checks (orphaned records) |
| Sites Export | Full site data CSV export |
| Sites with Plugin | Find all sites running a specific plugin |
| Paid Inactive | Paid plugins that are deactivated |
| Added/Deleted | Recent plugin installation/removal activity |
| Disconnected | MainWP disconnected sites |
| Vulnerability | Active vulnerability summary |
Admin Interface
Menu Structure
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']);