WP Manifestindependent plugin directory

Roko - The WordPress Butler

Roko quietly manages everything behind the scenes, spots stuff you didn't see, and offers one-click fixes.

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/josephgabito/roko/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Roko - WordPress Health & Performance Plugin

The loud-mouthed mechanic your WordPress site desperately needs.

Roko is a comprehensive WordPress optimization and health monitoring plugin that diagnoses performance bottlenecks, security vulnerabilities, plugin conflicts, and maintenance issues. Built with Domain-Driven Design (DDD) architectural patterns to demonstrate clean code practices in WordPress development.

🏗️ Architecture Overview

Roko demonstrates clean architecture principles with strict separation of concerns across four distinct layers. This example shows the Security domain - similar patterns are applied across Performance, Monitoring, and other domains:

graph TD
    subgraph "🌐 Presentation Layer"
        REST["SecurityJsonService<br/>REST API Endpoints"]
    end

    subgraph "🎯 Application Layer"
        APP["SecurityApplicationService<br/>Translates Business Codes"]
        INTRF["SecurityTranslationProviderInterface<br/>Infrastructure Contracts"]
    end

    subgraph "🏛️ Domain Layer"
        AGG["SecurityAggregate<br/>Emits Business Codes"]
        CHECKS["SecurityKeysChecks<br/>Pure Business Logic"]
        ENTITIES["Domain Entities<br/>SecurityKeys, Check, etc."]
    end

    subgraph "🔌 Infrastructure Layer"
        WP_TRANS["WpSecurityTranslationProvider<br/>WordPress Implementation"]
        WP_REPO["WpSecurityKeysProvider<br/>WordPress Data Access"]
        I18N["SecurityKeysChecksI18n<br/>Translation Strings"]
    end

    REST --> APP
    APP --> AGG
    AGG --> CHECKS
    CHECKS --> ENTITIES
    WP_TRANS -.->|implements| INTRF
    WP_REPO --> AGG
    WP_TRANS --> I18N

    classDef presentation fill:#e1f5fe
    classDef application fill:#f3e5f5
    classDef domain fill:#e8f5e8
    classDef infrastructure fill:#fff3e0

    class REST presentation
    class APP,INTRF application
    class AGG,CHECKS,ENTITIES domain
    class WP_TRANS,WP_REPO,I18N infrastructure

🎯 DDD Principles in Action

Layer Responsibilities

Layer May Import/Depend On Never Imports Example Classes
🌐 Presentation Application DTOs/Commands Domain or Infrastructure directly SecurityJsonService
🎯 Application Domain abstractions, owns interfaces Infrastructure concretes SecurityApplicationService
🏛️ Domain Nothing (pure) Infrastructure, frameworks, UI SecurityAggregate, SecurityKeysChecks
🔌 Infrastructure Domain types, Application interfaces Nothing above it WpSecurityTranslationProvider

Dependency Flow (Clean Architecture)

graph LR
    PRES[🌐 Presentation] --> APP[🎯 Application]
    APP --> DOM[🏛️ Domain]
    INFRA[🔌 Infrastructure] --> APP
    INFRA --> DOM

    DOM -.->|"❌ Never depends on"| INFRA
    APP -.->|"❌ Never imports"| INFRA

    classDef presentation fill:#e1f5fe
    classDef application fill:#f3e5f5
    classDef domain fill:#e8f5e8
    classDef infrastructure fill:#fff3e0

    class PRES presentation
    class APP application
    class DOM domain
    class INFRA infrastructure

📁 Project Structure

This shows the Security domain as an example - similar patterns are used for Performance, Monitoring, and other domains:

src/
├── 🏛️ Domain/
│   ├── Security/                          # Security Domain (shown as example)
│   │   ├── SecurityAggregate.php          # Aggregate Root
│   │   ├── Checks/
│   │   │   ├── SecurityKeysChecks.php     # Domain Service
│   │   │   └── ValueObject/
│   │   │       ├── Check.php              # Value Object
│   │   │       ├── CheckStatus.php        # Enum-like Value Object
│   │   │       └── Severity.php           # Enum-like Value Object
│   │   └── SecurityKeys/
│   │       ├── Entity/
│   │       │   └── SecurityKeys.php       # Domain Entity
│   │       └── ValueObject/
│   │           └── SecurityKey.php        # Value Object
│   ├── Performance/                       # Performance Domain (similar structure)
│   ├── Monitoring/                        # Monitoring Domain (similar structure)
│   └── ...                                # Other domains follow same patterns
├── 🎯 Application/
│   └── Security/                          # Application layer for Security domain
│       ├── SecurityApplicationService.php # Use Case Orchestrator
│       └── Provider/
│           └── SecurityTranslationProviderInterface.php # Contract
└── 🔌 Infrastructure/
    └── WordPress/                         # WordPress details, hooks, $wpdb, get_post, i18, etc
        ├── Plugin.php                     # DI Container & Bootstrap
        └── Security/                      # Infrastructure for Security domain
            ├── SecurityJsonService.php    # REST Controller
            ├── WpSecurityKeysProvider.php # Data Access
            ├── Provider/
            │   └── WpSecurityTranslationProvider.php
            └── I18n/
                └── SecurityKeysChecksI18n.php

🔍 Architecture Patterns

1. Domain Emits Business Codes

Domain entities emit business codes - Application layer handles translation:

// ✅ Domain emits business codes, never handles i18n
class SecurityKeysChecks {
    public static function fromSecurityKeys(SecurityKeys $securityKeys): self {
        // Pure business logic
        $recommendationCode = $strength . '_' . $source; // Business code: "weak_constant"

        return new Check(
            $id, $label, $status, $severity, $description, $evidence,
            $recommendationCode, // Domain emits codes like "SEC_KEY_WEAK"
            'roko'
        );
    }
}

// ✅ Application translates business codes to human text
class SecurityApplicationService {
    public function getSecuritySnapshot() {
        $domainSnapshot = $this->securityAggregate->snapshot(); // Gets business codes
        return $this->translateBusinessCodes($domainSnapshot);  // Converts to human text
    }
}

2. Single-Purpose Application Services

Each application service focuses on one specific use case:

// ✅ Focused, single-responsibility service
class SecurityApplicationService {
    public function getSecuritySnapshot() {
        // Get translations from infrastructure
        $recommendations = $this->translationProvider->getAllSecurityKeyRecommendations();

        // Let domain handle its own serialization
        return $this->securityAggregate->snapshot($recommendations);
    }
}

3. Interface Segregation

Clean contracts between layers:

// ✅ Application defines what it needs
interface SecurityTranslationProviderInterface {
    public function getAllSecurityKeyRecommendations();
}

// ✅ Infrastructure provides WordPress-specific implementation
class WpSecurityTranslationProvider implements SecurityTranslationProviderInterface {
    public function getAllSecurityKeyRecommendations() {
        // WordPress-specific translation logic
    }
}

4. Dependency Inversion Principle

Infrastructure implements interfaces defined by Application layer:

// ✅ Application defines the contract
interface SecurityTranslationProviderInterface {
    public function getAllSecurityKeyRecommendations();
}

// ✅ Infrastructure implements the contract
class WpSecurityTranslationProvider implements SecurityTranslationProviderInterface {
    public function getAllSecurityKeyRecommendations() {
        // WordPress-specific implementation.
        // Hooks lives here as well.
    }
}

// ✅ Application depends on abstraction, not concrete
class SecurityApplicationService {
    public function __construct(
        SecurityAggregate $securityAggregate,
        SecurityTranslationProviderInterface $provider  // ← Interface, not concrete
    ) {
        // Infrastructure implementation injected at runtime
    }
}

5. Dependency Injection at the Root

All dependencies wired at the application entry point:

// ✅ Clean dependency injection
class Plugin {
    public function init() {
        // Domain layer - pure business logic
        $securityAggregate = new SecurityAggregate(/*...*/);

        // Infrastructure providers (implement Application interfaces)
        $translationProvider = new WpSecurityTranslationProvider();

        // Application layer - receives Infrastructure via interfaces
        $securityApplicationService = new SecurityApplicationService(
            $securityAggregate,
            $translationProvider  // ← Concrete injected, but Application sees interface
        );

        // Presentation layer - REST API endpoints
        new SecurityJsonService($securityApplicationService);
    }
}

🤖 The Boring Ceremony

Once you have bulletproof patterns, adding new features becomes predictable and "boring" - exactly as it should be. Creative solutions introduce bugs. Not on this system.

The Iron Rule: Consistency > Creativity

Every security feature follows the exact same ceremony. No exceptions. No shortcuts. No "clever" workarounds.

❌ "Let me just bypass the repository this one time..."
❌ "I'll handle this edge case differently..."  
❌ "This feature is simple, no need for the full pattern..."
❌ "I know a clever way to do this..."

✅ Repository pattern? ALWAYS.
✅ Domain service? ALWAYS.
✅ Translation abstraction? ALWAYS.
✅ Business codes? ALWAYS.

The Ceremony (3 Simple Steps)

When adding any new security feature, just follow the existing pattern:

1. Domain Layer → Pure Business Logic

// Add your entities, value objects, and domain service
src/Domain/Security/SshKeys/
├── Entity/SshKeyCollection.php           # Your business data
├── ValueObject/SshKey.php               # Immutable values
└── ../../Checks/SshKeyChecks.php        # Transform into Check objects

class SshKeyChecks {
    public static function fromSshKeyCollection(SshKeyCollection $collection): self {
        // Pure business logic - emit business codes, never translate
        return new Check($id, $label, $status, $severity, $description, $evidence, 'ssh_key_weak', 'roko');
    }
}

2. Infrastructure Layer → WordPress Implementation

// Add repository and translation implementation
src/Infrastructure/WordPress/
├── Repository/WpSshKeyRepository.php              # Data access
└── Security/I18n/SshKeyChecksI18n.php            # Business code translations

class SshKeyChecksI18n {
    public static function recommendation($businessCode) {
        return ['ssh_key_weak' => __('Fix SSH keys...', 'roko')][$businessCode] ?? '';
    }
}

3. Wire Into Existing Pattern

// Just copy what SecurityKeysChecks, FileSecurityChecks, etc. already do:

// Add to SecurityAggregate.php (follow existing pattern):
$sshKeyChecks = SshKeyChecks::fromSshKeyCollection($this->sshKeyRepository->getCollection());
$snapshot['sections'][] = ['id' => 'ssh_keys', 'checks' => $sshKeyChecks->toArray()];

// Add to WpSecurityTranslationProvider.php (follow existing pattern):
public function getSshKeyRecommendation($code) { return SshKeyChecksI18n::recommendation($code); }

// Add to SecurityApplicationService.php (follow existing pattern):
if ($section['id'] === 'ssh_keys') { /* translate business codes */ }

That's it. Presentation layer (REST API) and Application layer (orchestration) already handle everything automatically.

Why This Approach Works

Bug Prevention

  • No creative solutions means no unexpected edge cases
  • Consistent patterns are easy to review and test
  • Standardized flow prevents architectural mistakes

Development Speed

  • No decision fatigue - follow the pattern, ship the feature
  • Copy-paste architecture enables faster implementation
  • Predictable debugging - issues appear in expected places

Team Efficiency

  • Code reviews focus on pattern compliance
  • Onboarding is simple - learn the pattern once, apply everywhere
  • No architectural debates - decisions already made

Frontend Automatic Support

The frontend JavaScript already handles your new feature automatically:

// ✅ Your new SSH key checks appear automatically
const sshSection = this.get_section('ssh_keys');  // Automatic
const failedSshChecks = this.get_checks_by_status('fail');  // Automatic
const sshCard = this.render_section_card('ssh_keys');  // Automatic

Zero Creativity Zone

// ❌ Creative Developer's Approach
if ($sshKeysVulnerable) {
    wp_die('SSH problem!'); // "Quick fix"
}

// ✅ Your System's Approach  
class SshKeyChecks {
    public static function fromSshKeyCollection(SshKeyCollection $collection): self {
        // Pure business logic
        // Predictable transformation  
        // Consistent with all other *Checks classes
        // Zero surprises
    }
}

🎯 The Result

After following this ceremony 4 times (SecurityKeys, FileSecurity, FileIntegrity, Vulnerabilities), you now have:

  • ✅ Bulletproof patterns that prevent bugs
  • ✅ Zero-decision development - just follow the steps
  • ✅ Self-documenting code - every feature looks identical
  • ✅ Junior-dev-proof architecture - impossible to break
  • ✅ Frontend that auto-adapts to new security features

Consistent patterns produce reliable results.

🔧 What Roko Does

Roko is your WordPress site's diagnostic tool, covering multiple areas:

🚀 Performance Optimization

  • Plugin Performance Heatmap: Identifies slow plugins dragging down load times
  • Database Optimization: Cleans up bloated tables and unused data
  • Core Web Vitals Tracking: Monitors TTFB, LCP, CLS metrics
  • Query Analysis: Spots inefficient database queries

🛡️ Security Health

  • Security Keys Analysis: Evaluates WordPress security keys and salts
  • File Integrity Monitoring: Detects unauthorized file modifications
  • Vulnerability Scanning: Checks for known security issues
  • File Permission Auditing: Validates proper file and directory permissions

🔍 Diagnostics & Monitoring

  • Plugin Conflict Detection: Isolates problematic plugin combinations
  • Multi-site Dashboard: Manages multiple WordPress installations
  • Health Check Scoring: Provides overall site health ratings
  • Smart Action Recommendations: Suggests specific fixes for issues

⚡ Quick Fixes

  • One-Click Optimizations: Database cleanup, cache purging, plugin updates
  • Auto-fix Security Issues: Resolves common security misconfigurations
  • Performance Tuning: Applies proven optimization techniques
  • Accessibility Improvements: Suggests alt-text and other accessibility fixes

Development Setup

  1. Clone and install dependencies:
    git clone https://github.com/JosephGabito/roko.git
    cd roko
    composer install

Development Workflow

Composer Scripts

Command Description
composer test Run all tests (syntax, compatibility, coding standards, unit tests)
composer phpunit Run unit tests only
composer test-unit Run unit test suite
composer phpcs Check WordPress Coding Standards
composer phpcbf Auto-fix coding standards issues
composer php74-compat Check PHP 7.4 compatibility
composer php70-compat Check PHP 7.0 compatibility
composer syntax-check Validate PHP syntax

Quick Commands

# Run all quality checks including unit tests
composer test

# Run just unit tests
composer phpunit

# Fix coding standards
composer phpcbf

# Check PHP 7.4 compatibility
composer php74-compat

Code Standards

  • Architecture: Domain-Driven Design (DDD) with clean architecture
  • Code Standards: WordPress Coding Standards (WPCS)
  • Compatibility: PHP 7.0+ compatibility
  • Autoloading: PSR-4 autoloading
  • Naming: Snake_case for methods and classes (WordPress convention)
  • Testing: Unit tested with PHPUnit
  • Type Safety: Strict typing where PHP version allows

🚀 Why This Architecture?

Understanding Dependency Direction

Presentation  →  Application  →  Domain
                  ↑              ↑
Infrastructure  ──┘──────────────┘

Key insight: Infrastructure serves higher layers by implementing their contracts:

  • Application defines interfaces → Infrastructure implements them
  • Domain stays pure → Never depends on external concerns
  • Domain emits business codes → Application translates to human text
  • Testability → Easy to mock Infrastructure implementations
  • Flexibility → Swap WordPress for Laravel/Symfony without changing Domain

Architecture principle: The Domain layer avoids outward dependencies by emitting business codes like weak_constant, strong_roko rather than translated text. This separation allows the Application layer to handle translation concerns independently from business logic.

Benefits

  • ✅ Maintainable: Clear separation of concerns
  • ✅ Testable: Easy to unit test business logic
  • ✅ Flexible: Easy to swap implementations
  • ✅ Scalable: Can handle complex business requirements
  • ✅ Framework-Independent: Domain logic works anywhere

Enterprise Patterns

  • Repository Pattern: Clean data access abstraction
  • Aggregate Root: Consistent domain boundaries
  • Value Objects: Immutable, self-validating data
  • Domain Services: Complex business logic coordination
  • Application Services: Use case orchestration
  • Dependency Inversion: High-level modules don't depend on low-level modules

Release

./bin/release.sh 1.0.0