Developer guide for local development with VS Code Dev Containers + Docker.
Ifthenpay payment gateway plugin for Moodle with a batteries‑included local dev setup (🐳 Docker + Dev Containers). It provides reproducible environments, coding standards, AMD build tasks, and ready‑to‑use Xdebug debugging.
- Runtime: Moodle · PHP ≥ 8.2 · Xdebug 3
- Database: MySQL 8.0
- Dev Environment: VS Code Dev Containers + docker-compose
- PHP Tooling: Composer · PHPCS (Moodle CS) · PHP-CS-Fixer · PHPStan · PHPMD
- JS/AMD: Node 20 + Grunt (uglify, watch)
- JS Tooling: ESLint (with JSDoc, Promise, Babel, Globals) · Stylelint (+ Stylistic plugin · Config Standard)
- Clone & open in VS Code Command Palette → “Dev Containers: Reopen in Container”.
- First run installs deps (
composer install,npm install) and executes the post‑start hook to link the plugin into Moodle. - Open Moodle:
http://localhost:8080(first run may show installer). - Open Database:
http://localhost:8081.
.
├─ .devcontainer/
│ ├─ devcontainer.json # Compose integration, ports, extensions, post-commands
│ ├─ Dockerfile.app # Moodle runtime (Bitnami) with Xdebug
│ ├─ Dockerfile.dev # VS Code dev image (CLI tools)
│ └─ post-start.sh # Symlink plugin into Moodle on shared volume
│
├─ .github/
│ └─ workflows/ # GitHub Actions CI/CD workflows
│
├─ .vscode/
│ ├─ launch.json # Xdebug launchers (web + CLI)
│ └─ ifthenpay-moodle.code-workspace
│
├─ src/ # Plugin source (PHP, templates, AMD JS under src/amd/*)
├─ vendor/ # Composer dependencies
├─ composer.json # PHP toolchain (PHPCS, PHP-CS-Fixer, PHPStan, PHPMD)
├─ node_modules/ # Node dependencies
├─ package.json # JS toolchain (Grunt, ESLint, Stylelint)
├─ Gruntfile.js # AMD build/watch tasks
├─ phpcs.xml # Coding standards (Moodle CS)
├─ phpstan.neon # Static analysis config
├─ docker-compose.yml # App, DB, dev services, volumes/ports
└─ (...) # Other configuration files
🔗 Symlink created on start
/workspace/bitnami/moodle/payment/gateway/ifthenpay → /opt/dev/ifthenpayLives on the Bitnami shared volume; it may look “dangling” inside the dev container but is valid for the app.
- Database:
ifthenpay-db– MySQL 8.0 (dev creds:moodleuser:userpass, DB:moodle). - App (Moodle): Bitnami Moodle 4.3 with Xdebug 3 enabled (dev creds:
admin:adminpass). - Dev: VS Code Dev Container (PHP 8.2 + Node 20 + grunt-cli).
Volumes
mysql_data– MySQL data.bitnami– Moodle code/data; also where the plugin symlink lives.
- Multi-root workspace: the repo ships a workspace with two roots → Plugin (repo) and Moodle Core + Data (bitnami), so navigation & search cover both.
- Intelephense indexing: Moodle core paths are pre-added to
includePathsso symbols resolve across roots. - Watch & search hygiene:
moodledata,cache, andtempare excluded from search/watch to keep VS Code snappy. - Xdebug mappings: preconfigured in
.vscode/launch.json(e.g.,/bitnami → /workspace/bitnamiand plugin →src/), so breakpoints bind without tweaks.
PHP (Composer)
composer run lint # PHPCS (Moodle CS)
composer run lint:fix # PHPCBF + PHP-CS-Fixer
composer run analyse # PHPStan
composer run qa # Lint + AnalyseJS / AMD (Grunt)
npm run build # Build AMD bundles (Grunt)
npm run watch # Watch & rebuild AMD bundles
npm run lint:js # Lint JavaScript (ESLint)
npm run lint:js:fix # Auto-fix JavaScript issues
npm run lint:css # Lint CSS (Stylelint)
npm run lint:css:fix # Auto-fix CSS issues
npm run lint # Run all linters
npm run lint:fix # Auto-fix all fixable issues- VS Code → Run and Debug → “Listen for Xdebug (Moodle web)” (port
9003). - Hit a page that executes your plugin code (e.g., settings/checkout) and breakpoints will bind.
- CLI: “Listen for Xdebug (CLI in dev)”.
- Plugin not detected → re-run:
bash .devcontainer/post-start.sh - Breakpoints not hit → use the correct listener and set a breakpoint early (e.g.,
lib.php). - Tools missing → run
composer install/npm installinside the container.
This plugin follows the official Moodle plugin structure & coding guidelines (see: Moodle Plugins docs, Payment gateway API). Classes are PSR‑4 autoloaded under paygw_ifthenpay\*, UI is rendered with Mustache, and browser JS is shipped as AMD modules compiled via Grunt.
src/
├─ amd/
│ ├─ src/
│ │ ├─ admin_gateway_form.js # Enhancements for the admin gateway form
│ │ ├─ gateways_modal.js # UI modal for method selection / UX helpers
│ │ └─ return.js # Return‑page UX (polling/spinner/retry)
│ └─ build/ # Minified AMD bundles (committed for releases)
│
├─ classes/
│ ├─ adminsetting/
│ │ └─ backofficekey.php # Custom admin setting + server-side validation
│ ├─ local/
│ │ ├─ api_client.php # HTTP client for ifthenpay endpoints
│ │ └─ data_formatter.php # Helpers for payloads/data types
│ ├─ privacy/
│ │ └─ provider.php # GDPR/privacy API implementation
│ └─ gateway.php # Gateway integration glue (Payment Account form/adapters)
│
├─ db/
│ ├─ install.xml # DB schema
│ └─ uninstall.php # Cleanup on uninstall
│
├─ lang/ # Language strings
├─ pix/ # Icons/assets
├─ templates/
│ └─ ifthenpay_button_placeholder.mustache # UI partials
│
├─ cancel.php # Cancel/error landing
├─ lib.php # Business logic (helper functions)
├─ pay.php # Starts a payment attempt
├─ return.php # Handles return from provider (poll + update)
├─ settings.php # Admin settings (Plugin Core settings)
├─ styles.css # Small admin/UI styles
├─ version.php # Component metadata (version/reqs)
└─ webhook.php # Server‑to‑server notifications (callback endpoint)
Notes: author AMD in
amd/src/*and build toamd/build/*vianpm run build(ornpm run watch). Ensure built files are committed for distribution.