All skills
michtio avatar

/craft-php-guidelines

@614a89e

Craft CMS 5 PHP coding standards and conventions. ALWAYS load when writing, editing, reviewing, or discussing any PHP in a Craft plugin or module — even small edits. Also when running ECS, PHPStan, or scaffolding with ddev craft make. Covers: PHPDoc blocks (@author, @since, @throws chains), section headers (=========), class organization, naming conventions (services, queue jobs, records, events, enums), defineRules() and validation, beforePrepare() and addSelect(), MemoizableArray, DateTimeHelper vs Carbon, strict_types/declare(strict_types=1), short nullable notation (?string), typed properties, void returns, control flow (early returns, match over switch), CP Twig template conventions, form macros, translations (Craft::t), ECS/PHPStan config, scaffolding commands, and the verification checklist. Triggers on: writing service classes, models, controllers, elements, element queries, records, queue jobs, migrations, or any PHP class in a Craft context; PHP code review, refactoring, or style questions; requireAdmin vs requirePermission, manage-settings, settings permission, kebab-case permission handles never camelCase, allowAdminChanges, read-only settings, getCpNavItem dead nav item, permission handle constant on owning controller, App::env() never getenv(), App::parseEnv() for $VAR settings, no-em-dash user-facing copy. NOT for front-end Twig (craft-twig-guidelines), template architecture (craft-site), or CP JavaScript/Garnish (craft-garnish). If you are touching PHP in a Craft context, you need this skill.

Use this Skill: https://skilld.dev/gh/michtio/craftcms-claude-skills/craft-php-guidelines

This session only. Nothing lands on disk.

referencesnaming-conventions.md

≈883 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Naming Conventions

General Naming

Thing Convention Example
Namespace All lowercase vendor\pluginhandle
Class StudlyCase MyEntity
Method camelCase getEntityById()
Private method Underscore prefix _registerCpUrlRules()
Yii-invoked method Public, no underscore validateSiteSettings() — see exception below
Property camelCase $entityId
Private property Underscore prefix $_items
Constant UPPER_SNAKE_CASE EVENT_BEFORE_SAVE
Table constant Craft format {{%pluginhandle_items}}
Event constant Before/after pattern EVENT_BEFORE_SAVE_ITEM
Config path Dot-separated pluginhandle.items
Enum StudlyCase BulkOperationStatus
Enum case PascalCase Processing

File Structure Naming

Type Convention Example
Plugin entry Named after the plugin Cockpit.php, Typesense.php, PasswordPolicy.php
Element Singular Entry.php, Asset.php, User.php
Element query Singular + Query EntryQuery.php, AssetQuery.php
Element action Action verb, no suffix Delete.php, Duplicate.php, SetStatus.php
Element condition Domain + ConditionRule SectionConditionRule.php, TypeConditionRule.php
Element exporter Descriptive, no suffix Expanded.php, Raw.php
Model Singular Section.php, Volume.php, EntryType.php
Record Same name as model Section.php, Volume.php (namespace distinguishes)
Service (resource) Plural Entries.php, Volumes.php, Users.php
Service (utility) Domain noun Auth.php, Search.php, Gc.php
Controller (resource) Plural + Controller EntriesController.php, SectionsController.php
Controller (action) Domain + Controller AppController.php, AuthController.php
Console controller Domain + Controller SyncController.php, ResaveController.php
Queue job Action verb phrase, no suffix ResaveElements.php, UpdateSearchIndex.php
Event Domain + Event SectionEvent.php, VolumeEvent.php
Register event Register + Domain + Event RegisterUrlRulesEvent.php
Define event Define + Domain + Event DefineHtmlEvent.php, DefineRulesEvent.php
Validator Domain + Validator HandleValidator.php, UniqueValidator.php
Helper Domain (suffix optional) Db.php, Cp.php, ArrayHelper.php
Enum Descriptive name PropagationMethod.php, CmsEdition.php
Migration Timestamped m240101_000000_add_column.php
Install migration Install.php Install.php

Record Aliasing

When importing both model and record in the same file, alias the record:

use vendor\myplugin\models\MyEntity;
use vendor\myplugin\records\MyEntity as MyEntityRecord;

Visibility Exception: Yii-Invoked Methods

Methods that Yii invokes by name from outside the class are public with no underscore prefix, even if they feel "internal." Yii resolves these by string name on the object — private or underscore-prefixed methods won't be found.

This applies to:

  • Inline validator methods referenced from defineRules() — 'validateSiteSettings'
  • when callables in validator rules — [$this, 'hasMaxRows']
  • Event handler methods referenced as strings in config
  • Behavior callables referenced by name

General principle: any method Yii invokes by name is part of the public API surface.

Source: SKILL.md on GitHub

No alerts16d3 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides comprehensive PHP coding standards, project organization rules, and development guidelines for Craft CMS 5. It emphasizes secure coding practices, such as implementing authorization parity across multiple application surfaces and using framework-specific helpers for environment access and date handling. No malicious patterns or security risks were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

Signed by skilld at 614a89e. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated 2 weeks ago

README badge

README badge for michtio/craftcms-claude-skills/craft-php-guidelines