Skip to content

PteroCA-Org/pteroca-plugin-hello-world

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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

Watchers

Forks

Packages

 
 
 

Contributors