# Craft Php Guidelines

> Craft CMS 5 PHP coding standards and conventions. ALWAYS load this skill when writing, editing, reviewing, or discussing any PHP file in a Craft CMS plugin or module — even for small edits. Also load when running ECS, PHPStan, or scaffolding with ddev craft make. Covers: PHPDoc blocks (@author, @since, @throws chains, documenting exceptions), section headers (=========), class organization, namin…

- **Type:** Skill
- **Install:** `agentstack add skill-sublimate-toe9304-craftcms-claude-skills-craft-php-guidelines`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [sublimate-toe9304](https://agentstack.voostack.com/s/sublimate-toe9304)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [sublimate-toe9304](https://github.com/sublimate-toe9304)
- **Source:** https://github.com/sublimate-toe9304/craftcms-claude-skills/tree/main/skills/craft-php-guidelines

## Install

```sh
agentstack add skill-sublimate-toe9304-craftcms-claude-skills-craft-php-guidelines
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Craft CMS 5 PHP Guidelines

Complete PHP coding standards and conventions for Craft CMS 5 plugin and module development. These extend Craft's official coding guidelines with project-specific conventions.

**Core principles:** PHPDocs on everything — classes, methods, and properties — regardless of type hints. No `declare(strict_types=1)` in plugin source files (matching Craft core convention).

## Companion Skills — Always Load Together

- **`craftcms`** — Architecture patterns, element lifecycle, controllers, events, migrations. Required for any Craft plugin or module development.
- **`ddev`** — All commands run through DDEV. Required for running ECS, PHPStan, scaffolding, and tests.

## Documentation

- Official coding guidelines: https://craftcms.com/docs/5.x/extend/coding-guidelines.html
- Class reference: https://docs.craftcms.com/api/v5/
- Generator reference: https://craftcms.com/docs/5.x/extend/generator.html

When unsure about a convention, `WebFetch` the coding guidelines page for the authoritative answer.

## Common Pitfalls

- `addSelect()` is the convention in `beforePrepare()` — safely additive when multiple extensions contribute columns.
- `$_instances` is not a Craft convention — private properties use underscore prefix but meaningful names like `$_items`, `$_sections`.
- Records use the **same class name** as models (namespace distinguishes). Alias when importing both: `use ...\records\MyEntity as MyEntityRecord;`.
- Queue jobs have **no "Job" suffix** — `ResaveElements`, not `ResaveElementsJob`.
- `declare(strict_types=1)` is NOT used in plugin source files. Only in standalone config files like `ecs.php`.
- `@author` goes on classes and methods only — never on properties.
- Don't use `string|null` — use `?string` (short nullable notation).
- Forget `parent::defineRules()` and you lose all inherited validation.
- `DateTimeHelper` in elements/queries, `Carbon` in services — never mix in the same class.
- Missing `@throws` chains — document exceptions from called methods too, not just your own throws.
- Using magic property access (`$plugin->settings`, `$app->view`) instead of explicit getters (`$plugin->getSettings()`, `$app->getView()`) — PHPStan can't resolve `__get()` calls, so magic access passes at runtime but fails static analysis. Always use explicit getters for Yii2 components and Craft plugin properties.

## Reference Files

Read the relevant reference file(s) for your task:

| Task | Read |
|------|------|
| Writing PHPDocs, `@author`, `@since`, `@throws`, `@var`, `@param`, type references | `references/phpdoc-standards.md` |
| Class structure, section headers, ordering, enums, control flow, comments, whitespace | `references/class-organization.md` |
| Naming classes, methods, properties, files, services, events, migrations | `references/naming-conventions.md` |
| CP Twig templates, form macros, translations, file headers, validation | `references/templates-and-patterns.md` |
| ECS, PHPStan, scaffolding commands, commit messages | `references/tooling.md` |

## Critical Rules

1. PHPDocs on everything: classes, methods, properties. No exceptions.
2. `@throws` chains: document every exception including uncaught from called methods.
3. `@author` and `@since` at the bottom of class/method docblocks, after a blank line.
4. Section headers with `// =========================================================================` on every class.
5. `declare(strict_types=1)` is NOT used in plugin source files — Craft's internal type coercion depends on PHP's default weak typing mode.
6. Private methods/properties prefixed with underscore: `_registerCpUrlRules()`, `$_items`.
7. `addSelect()` convention in `beforePrepare()` — additive across extensions, prevents column conflicts.
8. `DateTimeHelper` in elements/queries, `Carbon` in services — separate concerns prevent mixing date APIs in the same class.
9. Always scaffold with `ddev craft make  --with-docblocks`, then customize.
10. `ddev composer check-cs` and `ddev composer phpstan` must pass before every commit.

## PHP Standards

- Minimum PHP 8.2 (Craft CMS 5 requirement).
- PSR-12 baseline with Craft modifications (trailing commas, constant visibility).
- `craftcms/ecs` with `SetList::CRAFT_CMS_4` preset (covers both Craft 4 and 5).
- Short nullable notation: `?string` not `string|null`.
- Always specify `void` return types.
- Typed properties everywhere. No untyped public properties.
- Strict comparison always: `$foo === null`, `in_array($x, $y, true)`.
- Casts over functions: `(int)$foo` not `intval($foo)`.

## Section Header Order

```
// Traits
// Const Properties
// Static Properties
// Public Properties
// Protected Properties
// Private Properties
// Public Methods
// Protected Methods
// Private Methods
```

Only include sections that have content. Blank line after the separator, before the first item.

## Control Flow

- **Happy path last.** Handle error conditions first with early returns.
- **Avoid `else`** — use early returns instead.
- **`match` over `switch`** — always.
- **Always use curly brackets** even for single statements.
- **Separate compound conditions** into nested `if` statements for readability.
- **Named arguments** when calling methods with 3+ parameters.

## Date Handling

- **Elements and element queries**: `craft\helpers\DateTimeHelper`.
- **Services** (date arithmetic): `Carbon\Carbon`.
- Never mix both in the same class.

## Database Conventions

- `[[column]]` quoting in Yii2 join conditions.
- `addSelect()` in `beforePrepare()` — safely additive.
- `postDate` and `expiryDate` in `addSelect()` and indexed on element tables.
- `Db::parseParam()` for query parameters. `Db::parseDateParam()` for dates.
- Foreign keys with explicit `CASCADE` / `SET NULL` behavior.

## Naming Quick-Reference

| Thing | Convention | Example |
|-------|-----------|---------|
| Services (resource) | Plural | `Entries`, `Volumes`, `Users` |
| Services (utility) | Domain noun | `Auth`, `Search`, `Gc` |
| Queue jobs | Action verb, no suffix | `ResaveElements`, `UpdateSearchIndex` |
| Records | Same name as model | Namespace distinguishes |
| Events | Three patterns | `SectionEvent`, `RegisterUrlRulesEvent`, `DefineHtmlEvent` |
| Element actions | Action verb, no suffix | `Delete`, `Duplicate`, `SetStatus` |
| Enums | PascalCase cases, string/int backed | `PropagationMethod`, `CmsEdition` |

For the complete naming reference including file structure conventions, read `references/naming-conventions.md`.

## Verification Checklist

Before every commit:

1. `ddev composer check-cs` passes
2. `ddev composer phpstan` passes
3. Tests green
4. PHPDocs complete on all new/modified code
5. `@throws` chains verified
6. Section headers present and correct
7. Imports alphabetical and grouped

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [sublimate-toe9304](https://github.com/sublimate-toe9304)
- **Source:** [sublimate-toe9304/craftcms-claude-skills](https://github.com/sublimate-toe9304/craftcms-claude-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-sublimate-toe9304-craftcms-claude-skills-craft-php-guidelines
- Seller: https://agentstack.voostack.com/s/sublimate-toe9304
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
