Best Practices
Guidelines for creating secure, performant, and maintainable plugins.
Security
Never Use Dangerous Functions
Forbidden functions:
eval(),exec(),shell_exec(),system()passthru(),popen(),proc_open()Dynamic
require/includewith user input
// BAD - Security vulnerability
eval($_GET['code']);
exec('rm -rf ' . $userInput);
// GOOD - Use safe alternatives
$sanitizedInput = escapeshellarg($userInput);
exec('safe-command ' . $sanitizedInput);Validate All Input
use Symfony\Component\Validator\Constraints as Assert;
#[Assert\NotBlank]
#[Assert\Email]
private string $email;
#[Assert\Length(min: 8, max: 100)]
private string $password;
#[Assert\Range(min: 1, max: 100)]
private int $age;Use Parameterized Queries
Sanitize Output
Encrypt Sensitive Data
Validate Webhooks
Performance
Use Caching
Optimize Database Queries
Add Database Indexes
Lazy-Load Heavy Services
Minimize Asset Size
Minify CSS/JS for production
Optimize images (compress, WebP format)
Use CDNs for common libraries
Bundle and compress assets
Batch Operations
Code Quality
Follow PSR-12 Coding Standards
Use Type Hints
Document Public Methods
Handle Errors Gracefully
Log Important Operations
Keep Classes Focused
Compatibility
Specify Version Constraints
Test with Minimum Version
Always test your plugin with the minimum PteroCA version you support.
Document Breaking Changes
In CHANGELOG.md:
Provide Upgrade Guides
Help users migrate between major versions with clear upgrade documentation.
Plugin Structure
Organize by Feature
Use Consistent Naming
Classes:
PascalCaseMethods:
camelCaseConstants:
UPPER_SNAKE_CASEDatabase tables:
plg_prefix_table_name
Separate Concerns
Controllers: Handle HTTP
Services: Business logic
Repositories: Data access
Entities: Data models
Database
Use Migrations for Schema Changes
Always Use Table Prefix
Add Indexes for Performance
Handle DateTime Correctly
User Experience
Provide Clear Error Messages
Use Translations
Show Progress for Long Operations
Validate Forms
Testing
Write Tests
Test Edge Cases
Empty input
Invalid data
Boundary values
Error conditions
Use Meaningful Test Names
Documentation
Document Public APIs
Every public method should have PHPDoc.
Provide README.md
Include in your plugin:
Maintain CHANGELOG.md
Track all changes between versions.
Include Examples
Provide code examples in documentation.
Avoid Common Pitfalls
Don't Modify Core Files
Never edit PteroCA core code. Use events and services instead.
Don't Use Global State
Don't Hardcode Paths
Don't Skip Error Handling
Always handle potential exceptions, especially in:
External API calls
File operations
Database queries
Related Guides
Testing - Test your plugin thoroughly
Security - Security guidelines
Plugin Structure - Organization
Last updated