Files
XC_VM/.github/instructions/php-conventions.instructions.md
T
Divarion_D 2abd19b0d5 chore(github): add composer to dependabot, fix stale AI instructions
dependabot.yml: the comment claimed "no Composer/npm manifests committed",
but src/composer.json + composer.lock ARE committed. Added a grouped
composer ecosystem (directory /src) so the 4 prod deps and the dev tools
get advisory monitoring; noted the production-only vendor recommit step.

instructions/php-conventions + architecture-rules: rewritten to the
current Composer PSR-4 architecture. They previously described the
pre-migration state and misdirected Copilot:
- "No autoloading via Composer — custom src/autoload.php" (file removed)
  and "Do NOT introduce Composer dependencies" → Composer PSR-4, vendor
  committed production-only, dump-autoload workflow
- lowercase paths (src/cli, src/core, src/modules, …) → real PascalCase
  (src/Cli, src/Core, src/Modules, src/Streaming, …)
- setDb() / $r-prefix (both gone from the codebase) → DatabaseAware +
  self::db(); dropped the dead $r naming rule
- inverted namespace guidance → new code is namespaced; legacy coexists,
  don't mass-migrate
- dangling ARCHITECTURE.md ref → docs/en/development/architecture.md
  (which exists), src/config/modules.php path fixed
2026-08-07 20:11:26 +03:00

54 lines
3.8 KiB
Markdown

---
applyTo: "**/*.php"
---
# PHP Conventions — XC_VM
XC_VM is a PHP 8.1+ modular monolith **migrated to Composer PSR-4** (`XcVm\` → `src/`).
The application root is `src/` (composer.json, vendor/, bootstrap.php all live there).
`short_open_tag=1` is on — view templates use `<?` / `<?=`.
## Formatting
- **Brace style:** K&R (opening brace on the same line)
- **Indentation:** tabs (1 tab per level), NOT spaces
- **No trailing whitespace**
## Autoloading & dependencies
- **Composer PSR-4:** `XcVm\` maps to `src/` (e.g. `XcVm\Core\Database\DatabaseHandler` = `src/Core/Database/DatabaseHandler.php`). Modules load via their own namespace autoloader, not the Composer PSR-4 map.
- **`vendor/` is committed and PRODUCTION-ONLY.** Never run `composer install` on a deploy path. To change the autoload map, run `composer dump-autoload` from `src/`. After changing deps, re-commit a `composer install --no-dev` vendor and `composer.lock`.
- **Don't add dependencies casually** — a new Composer package means a lockfile update and a production-only vendor recommit. Prefer the standard library or existing vendored libs.
## Namespaces & strict types (new code)
- **New PHP files** declare a namespace under `XcVm\…` matching their path, and start with `declare(strict_types=1)`.
- **Legacy first-party files** that are not yet namespaced (roughly half the tree) still exist. Do NOT mass-migrate them: only add a namespace / `strict_types` when you are already rewriting that file for another reason. Match the surrounding file when editing.
- Modules are namespaced `XcVm\Module\{Pascal}` with the class `{Pascal}Module` in `src/Modules/{name}_{hash5}/`.
## Database access
- **New code** uses the `DatabaseAware` trait: `use \XcVm\Infrastructure\Database\DatabaseAware;` then call `self::db()` (it resolves the connection from the `DatabaseFactory` singleton). Do NOT reintroduce per-class `setDb()` wiring.
- `Core/Database/DatabaseHandler` is the PDO wrapper. Query with `?` placeholders, never named parameters: `self::db()->query('SELECT * FROM streams WHERE id = ?;', $id)`. Terminate the SQL string with a semicolon.
- Legacy superglobals (`$db`, `$rSettings`, `$rUserInfo`, `$rServers`) are still bridged by `LegacyInitializer` for legacy code — preserve them when editing legacy files, but never introduce new global state in new code.
## Naming
- **Classes:** PascalCase (`StreamService`, `DatabaseHandler`)
- **Methods:** camelCase (`getById`, `processStream`)
- **Constants:** UPPER_SNAKE_CASE; for typed sets prefer enums (`BootContext`, `ModuleState`) over new string constants
- **DB columns in queries:** snake_case as stored
## Class patterns
- New domain code follows **Controller → Service → Repository** (see `docs/en/development/architecture.md`).
- Prefer constructor injection for collaborators; use the `DatabaseAware` trait for the shared connection.
## Comments
- **New code:** English comments and DocBlocks (keep `@param`, `@return`, `@package` tags in English).
- **Legacy files** carry Russian-language DocBlocks in some files. Do NOT mass-translate; translate only a file you are already editing for another reason, or when asked. Don't mix languages within one comment block.
## Error handling
- Prefer typed exceptions from the `XcVmException` hierarchy for new code.
- For fatal API responses the codebase uses `exit(json_encode(...))` — match the surrounding handler.
- Do NOT wrap existing code in try-catch "just in case".
## What NOT to do
- Do NOT run `composer install` on a deploy path, and do NOT add Composer dependencies casually.
- Do NOT reintroduce `setDb()` static injection or new `global` usage in new code.
- Do NOT mass-migrate legacy files to namespaces / `strict_types` / DI without an explicit request — keep changes surgical.
- Do NOT add PHPDoc or type annotations to unchanged code.