Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hello World Plugin

Comprehensive example plugin for PteroCA demonstrating all major plugin system capabilities.

This plugin serves as a reference implementation for plugin developers, showcasing best practices and patterns for extending PteroCA functionality.

Official Documentation

For complete plugin development documentation, visit:

Overview

The Hello World plugin demonstrates:

  • All 7 plugin capabilities (routes, entities, migrations, ui, eda, console, cron)
  • Plugin settings integration across all components
  • Multiple widget types and contexts
  • Essential event subscriptions
  • Entity relationships and custom repositories
  • Custom services and bootstrap initialization
  • Professional code documentation

Features Demonstrated

1. Settings Management (11 Settings)

Demonstrates all setting types and hierarchies:

General Settings:

  • greeting_message (string) - Customizable greeting
  • enable_widget (boolean) - Toggle widget visibility
  • max_visits_to_display (integer) - Limit for visit lists
  • welcome_text (string) - Multi-line welcome message
  • notification_level (string) - Log level: debug, info, warning, error

API Settings:

  • api_enabled (boolean) - Toggle API access
  • api_key (string) - Secure API key storage
  • api_rate_limit (integer) - Request limit

Advanced Settings:

  • enable_statistics (boolean) - Toggle statistics tracking
  • cleanup_days (integer) - Data retention period
  • debug_mode (boolean) - Enable debug logging

2. Widgets (3 Widgets, Multiple Contexts)

HelloWidget

  • Context: DASHBOARD
  • Position: RIGHT
  • Demonstrates: Settings integration (greeting_message, enable_widget)

StatsWidget

  • Contexts: DASHBOARD, ADMIN_OVERVIEW
  • Position: LEFT
  • Demonstrates: Multi-context support, context-aware data, EntityManager injection

QuickActionsWidget

  • Context: DASHBOARD
  • Position: NAVBAR
  • Demonstrates: Global navigation widget, dropdown menu

3. Event Subscribers (5 Subscribers, 7+ Events)

UserEventSubscriber

  • UserLoggedInEvent - Track user logins
  • UserRegisteredEvent - Welcome new users

ServerEventSubscriber

  • ServerCreatedOnPterodactylEvent - Log server creation
  • ServerPurchaseCompletedEvent - Track purchases

MenuEventSubscriber

  • MenuItemsCollectedEvent - Add navigation menu items (Hello World link, Visit Logs CRUD)

ServerTabSubscriber

  • ServerTabsCollectedEvent - Register custom server tabs

HelloEventSubscriber

  • DashboardAccessedEvent - Log dashboard access

4. Database Entities & Relationships

VisitLog Entity

  • Table: plg_hello_visit_log
  • Fields: id, visitorName, ipAddress, userAgent, message, createdAt
  • Relationship: OneToMany with Statistic
  • Repository: VisitLogRepository with 7 custom query methods

Statistic Entity

  • Table: plg_hello_statistic
  • Fields: id, type, value, metadata (JSON), createdAt
  • Relationship: ManyToOne with VisitLog
  • Demonstrates: JSON storage, entity relationships, indexed queries

5. Custom Repository (VisitLogRepository)

Custom query methods:

  • findRecentVisits() - Get latest visits
  • getStatsByPeriod() - Aggregated statistics
  • cleanupOldVisits() - Bulk delete old records
  • findByVisitorName() - Case-insensitive search
  • getDailyVisitCounts() - Trend analysis
  • findVisitsWithStatistics() - Eager loading (avoid N+1)
  • countTotal() - Simple count query

6. Custom Service (StatisticsService)

Business logic for statistics:

  • trackEvent() - Create statistics with metadata
  • getStatsByType() - Filter by type and period
  • aggregateStats() - Calculate sum, avg, min, max
  • getAllTypes() - List unique types
  • cleanupOldStatistics() - Data retention

7. Bootstrap Class

Plugin initialization:

  • Sets default settings on enable
  • Validates configuration
  • Initializes plugin defaults
  • Provides cleanup method
  • Comprehensive error handling

8. Console Commands & Cron Tasks

Console Command:

  • hello-world:greet - Demonstrates CLI integration

Cron Tasks:

  • HelloCleanupTask - Daily cleanup (3:00 AM)
  • Schedule: 0 3 * * *
  • Uses configurable cleanup_days setting

9. Routing & Controllers

HelloController (4 routes):

  • GET / - Main plugin page
  • GET /greet/{name} - JSON greeting endpoint
  • GET /info - Plugin metadata
  • GET /visits - Visit statistics

VisitLogCrudController (Admin CRUD):

  • Full EasyAdmin CRUD interface for Visit Logs
  • Demonstrates: List, detail, delete operations
  • Shows how plugins can create admin panel interfaces

10. Server Tabs

ExampleTab

  • ID: hello_world_example
  • Label: "Hello World"
  • Priority: 10 (appears at the end)
  • Demonstrates: Custom tabs on server management pages
  • Template: @PluginHelloWorld/tabs/example.html.twig

11. Translations & Assets

Translations:

  • plugin_hello_world.en.yaml - English translations
  • plugin_hello_world.pl.yaml - Polish translations (auto-generated)

Assets:

  • css/hello-world.css - Widget and page styles
  • js/hello-world.js - Interactive features
  • images/hello-logo.svg - Plugin logo

Installation

1. Plugin Placement

# Place plugin in plugins directory
cp -r hello-world /path/to/panel/plugins/

2. Discovery & Registration

# Scan for new plugins
php bin/console plugin:scan

# Enable the plugin
php bin/console plugin:enable hello-world

3. Database Setup

Migrations run automatically on enable:

  • Version20251101000001.php - Creates plg_hello_visit_log table
  • Version20251214000001.php - Creates plg_hello_statistic table with relationships
  • Version20251214000002.php - Initializes default plugin settings in database
  • Sets up indexes for performance

4. Configuration

Access via: Admin Panel → Settings → Plugin: hello-world

Configure:

  • Greeting messages
  • Widget visibility
  • Statistics tracking
  • API access
  • Data retention

Development Guide

Using This Plugin as a Reference

For Settings Integration:

// In any class with PluginSettingService injected
$value = $this->pluginSettingService->get('plugin-name', 'setting_key', 'default');

For Event Subscription:

class MyEventSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [EventClass::class => 'onEventMethod'];
    }
}

For Custom Widgets:

class MyWidget implements WidgetInterface
{
    public function getSupportedContexts(): array
    {
        return [WidgetContext::DASHBOARD];
    }

    public function isVisible(WidgetContext $context, array $contextData): bool
    {
        // Check settings, user roles, etc.
        return true;
    }
}

For Entity Relationships:

#[ORM\ManyToOne(targetEntity: ParentEntity::class, inversedBy: 'children')]
#[ORM\JoinColumn(onDelete: 'SET NULL')]
private ?ParentEntity $parent = null;

For Custom Repositories:

#[ORM\Entity(repositoryClass: 'Plugins\MyPlugin\Entity\Repository\MyRepository')]
class MyEntity { }

For Bootstrap Initialization:

{
  "bootstrap_class": "Plugins\\MyPlugin\\Bootstrap"
}

File Structure

hello-world/
├── plugin.json                          # Manifest (11 settings, bootstrap config)
├── Bootstrap.php                        # Plugin initialization
├── Migrations/
│   ├── Version20251101000001.php       # Create visit_log table
│   ├── Version20251214000001.php       # Create statistic table with relationships
│   └── Version20251214000002.php       # Initialize default settings
├── src/
│   ├── Controller/
│   │   ├── HelloController.php         # 4 routes (GET only)
│   │   └── Admin/
│   │       └── VisitLogCrudController.php # EasyAdmin CRUD for Visit Logs
│   ├── Entity/
│   │   ├── VisitLog.php               # Main entity with relationships
│   │   ├── Statistic.php              # Related entity with JSON metadata
│   │   └── Repository/
│   │       └── VisitLogRepository.php # 7 custom query methods
│   ├── EventSubscriber/
│   │   ├── HelloEventSubscriber.php   # Dashboard events
│   │   ├── UserEventSubscriber.php    # User lifecycle events
│   │   ├── ServerEventSubscriber.php  # Server events
│   │   ├── MenuEventSubscriber.php    # Navigation customization
│   │   └── ServerTabSubscriber.php    # Server tabs registration
│   ├── Tab/
│   │   └── ExampleTab.php             # Custom server tab
│   ├── Widget/
│   │   ├── HelloWidget.php            # DASHBOARD/RIGHT widget
│   │   ├── StatsWidget.php            # Multi-context/LEFT widget
│   │   └── QuickActionsWidget.php     # NAVBAR widget
│   ├── Service/
│   │   └── StatisticsService.php      # Business logic service
│   ├── Command/
│   │   └── HelloGreetCommand.php      # CLI command
│   └── CronTask/
│       └── HelloCleanupTask.php       # Scheduled task
├── Resources/
│   ├── config/
│   │   └── services.yaml              # Service definitions
│   ├── views/
│   │   ├── hello/
│   │   │   └── index.html.twig        # Main page template
│   │   └── widgets/
│   │       ├── hello.html.twig        # Widget templates
│   │       ├── stats.html.twig
│   │       └── quick_actions.html.twig
│   └── translations/
│       └── messages.en.yaml           # Base translations
├── assets/
│   ├── css/hello-world.css            # Plugin styles
│   ├── js/hello-world.js              # Plugin JavaScript
│   └── images/hello-logo.svg          # Plugin logo
├── templates/
│   ├── index.html.twig                # Additional templates
│   ├── tabs/
│   │   └── example.html.twig          # Server tab template
│   └── widgets/
│       ├── hello.html.twig            # Widget templates (duplicates for compatibility)
│       ├── stats.html.twig
│       └── quick_actions.html.twig
├── translations/
│   ├── plugin_hello_world.en.yaml     # Plugin-specific translations
│   └── plugin_hello_world.pl.yaml     # Auto-generated Polish
└── README.md

Testing

Manual Testing

  1. Settings:

    • Go to Settings → Plugin: hello-world
    • Change greeting_message and verify in widget
    • Toggle enable_widget and check dashboard
  2. Widgets:

    • Check dashboard for all 3 widgets
    • Verify navbar dropdown appears
    • Check admin overview for stats widget
  3. Events:

    • Login to trigger UserLoggedInEvent
    • Create server to trigger ServerCreatedOnPterodactylEvent
    • Check menu for "Hello World" items and "Visit Logs" link
  4. Database & CRUD:

    • Visit /plugins/hello-world/ to create visit logs
    • Check tables: plg_hello_visit_log, plg_hello_statistic
    • Access Visit Logs CRUD via admin panel menu
  5. Server Tabs:

    • Visit any server management page
    • Look for "Hello World" tab at the end of tabs list

CLI Testing

# Test console command
php bin/console hello-world:greet World --yell

# Test cron task manually
php bin/console plugin:cron:run

Key Implementation Highlights

✅ Bug Fixes

  • Fixed HelloCleanupTask.php:36 - Changed v.visitedAt to v.createdAt
  • Resolved TODOs in HelloWidget.php - Settings now fully integrated

✅ Settings Best Practices

  • All types demonstrated: string, integer, boolean
  • Three hierarchies: general, api, advanced
  • Settings used throughout all components
  • Default values initialized via migration

✅ Multi-Context Widgets

  • Different data per context (user vs system stats)
  • Conditional visibility based on settings
  • Multiple positions (LEFT, RIGHT, NAVBAR)

✅ Event-Driven Architecture

  • User lifecycle events (login, registration)
  • Server events (creation, purchase)
  • Menu customization (navigation injection)
  • Server tabs registration (custom tabs on server pages)

✅ Database Patterns

  • Bidirectional relationships (OneToMany/ManyToOne)
  • JSON metadata storage
  • Custom repository methods
  • Query optimization with indexes
  • EasyAdmin CRUD integration for entity management

✅ Service Layer

  • Business logic separation
  • Dependency injection
  • Error handling and logging
  • Settings integration

✅ Professional Code Quality

  • Comprehensive PHPDoc comments
  • Type hints throughout
  • Error handling
  • Logging at appropriate levels
  • Clean code organization

Common Patterns Used

1. Settings Retrieval

$value = $this->pluginSettingService->get('hello-world', 'setting_name', 'default_value');

2. Widget Visibility

public function isVisible(WidgetContext $context, array $contextData): bool
{
    return (bool) $this->pluginSettingService->get('hello-world', 'enable_widget', true);
}

3. Event Logging

$this->logger->info('Plugin: Event occurred', [
    'event_id' => $event->getEventId(),
    'data' => $event->getData(),
]);

4. Query Building

$qb = $this->entityManager->createQueryBuilder();
$results = $qb->select('e')
    ->from(Entity::class, 'e')
    ->where('e.field = :value')
    ->setParameter('value', $value)
    ->getQuery()
    ->getResult();

Next Steps for Developers

To extend this plugin or create your own:

  1. Study the Code: Read through each file to understand patterns
  2. Modify Settings: Add your own config_schema entries
  3. Create Widgets: Copy widget structure for your use case
  4. Subscribe to Events: Find events in src/Core/Event/ and subscribe
  5. Add Entities: Create tables following naming convention
  6. Build Services: Extract business logic into services
  7. Test Thoroughly: Test settings, events, widgets, database

Additional Resources

License

MIT License - Free to use and modify for your own plugins.

Support

This is a reference plugin for learning purposes. For questions about the PteroCA plugin system, consult the official documentation or visit the community forums.


Version: 1.0.0 Author: PteroCA Team Updated: 2025-12-28 Compatible: PteroCA 0.6.0 - 1.0.0

About

Example “Hello World” plugin for PteroCA, demonstrating plugin structure, lifecycle hooks, and basic panel integration.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages