Poweradmin Development Guide¶
Note: The repository's own CONTRIBUTING.md is the canonical source for branch targeting, commit conventions and the pull request process. This page covers the development environment and project layout.
Development Environment Setup¶
Prerequisites¶
- PHP 8.2 or higher
- MySQL/MariaDB, PostgreSQL, or SQLite
- Composer
- A PowerDNS server for testing
- Node.js and npm, only if you intend to run the Playwright end-to-end tests
Option 1: Devcontainer (recommended)¶
The repository ships a devcontainer providing MariaDB, PostgreSQL, SQLite and Adminer, with instances of Poweradmin already configured against each. Open the repository in VS Code with the Dev Containers extension and reopen in the container.
Load the test users with:
Option 2: Manual setup¶
1. Clone the repository:
2. Install dependencies:
3. Configure the application:
cp config/settings.defaults.php config/settings.php
# Edit config/settings.php with your database and PowerDNS settings
Never edit config/settings.defaults.php itself. It is the reference for every available setting
and is overwritten on upgrade.
Project Structure¶
Core components¶
- lib/: core library code, following Domain-Driven Design
- Domain/: business logic, entities and value objects
- Application/: controllers and services
- Infrastructure/: database access, the PowerDNS API client, LDAP and other external services
Entry points are index.php, dynamic_update.php and install/index.php.
Frontend¶
- assets/: JavaScript and images
- templates/: Twig templates, with a
defaultand amoderntheme
The two themes must stay in sync except for the files listed in
templates/theme-specific-templates.txt. composer lint:themes enforces this.
Testing¶
- tests/: PHPUnit suites (
unit,integration,functional,api,sql,docker) - playwright/: end-to-end browser tests
See the Testing Guide.
Documentation¶
The public API is described by docs/api/openapi.json in the docs repository, generated
from the controller attributes. Regenerate it from a poweradmin checkout after changing
the API (the docs repository's drift check fails when it is stale):
A running instance also serves the same specification live at /api/docs/v2/json when
api.docs_enabled is on.
A browsable class reference for lib/ is published from the develop branch at
docs.poweradmin.org/reference. The docs deploy builds it
with Doctum on every run, so it is never committed. To build it locally (the script downloads the
phar on first use and writes static HTML to docs/reference/, also ignored):
composer lint:docblocks runs the same parser without building and fails on any @param
tag that does not match the method signature. It is part of composer lint:all and CI.
Testing¶
Poweradmin has unit, integration, functional, API and end-to-end tests. See the Testing Guide for the layout and the commands.
Continuous Integration¶
- The project uses GitHub Actions for CI
- Ensure the tests and the static analysis gate pass before submitting pull requests
Coding Standards¶
Poweradmin follows PSR-12 with project-specific modifications. See the Coding Standards Guide.
Database Schema Changes¶
Schema changes ship as SQL scripts in sql/, named for the release that introduces them, for
example poweradmin-mysql-update-to-4.5.0.sql. A change needs one script per supported database:
MySQL, PostgreSQL and SQLite.
Write them so they can be applied more than once, using INSERT IGNORE or
ON CONFLICT DO NOTHING and name-based lookups rather than hardcoded IDs.
Warning: Poweradmin must never alter PowerDNS-owned tables such as
domainsandrecords. Anything Poweradmin needs to persist belongs in its own tables.
Contributing¶
- Fork the repository
- Create a feature branch
- Make your changes
- Run the tests and the quality checks
- Submit a pull request against the branch named in CONTRIBUTING.md
Contribution guidelines¶
- Code Quality: follow the project's style and standards
- Testing: add tests for new functionality and make sure the existing ones pass
- Documentation: user-visible changes deserve a pull request against the poweradmin-docs repository
Attribution policy¶
All meaningful contributions are credited in release notes. Please note:
- Sometimes similar ideas come from multiple contributors; implementation quality determines which is merged
- Contributions may be partially accepted or rewritten to maintain project consistency
- Even if your exact code isn't used, your ideas will still be credited if they influence the final implementation
If you notice your contribution hasn't been acknowledged in the release notes, please reach out. We want to ensure everyone receives proper recognition.
Internationalization¶
- Translation files live in
locale/ - New user-visible strings must be wrapped in
_()so they can be translated - See the Translations Guide
Security Considerations¶
- Always validate user input
- Use prepared statements for database queries, binding
PDO::PARAM_INTfor LIMIT, OFFSET and ID values - Access request data through the
Requestclass rather than$_GET,$_POSTor$_REQUEST - Read session state through
UserContextServicerather than$_SESSIONdirectly - Every POST route is CSRF validated; forms render the token with the
csrf_field()macro - Zone ownership is both direct and group-based, so permission checks must cover both