Extend DocBlockTagOrder to class/interface/trait docblocks#59
Merged
Conversation
Adds a configurable `classOrder` property (default: template, extends, implements, property, property-read, property-write, method, mixin) so class-level docblocks get the same consistent tag ordering that function/method docblocks already enforce. Makes the existing `order` property public so both can be overridden via XML configuration.
dereuromark
added a commit
to dereuromark/cakephp-ide-helper
that referenced
this pull request
May 9, 2026
Match the class-level tag order proposed in php-collective/code-sniffer#59: template, extends, implements, property, property-read, property-write, method, mixin Previously addBehaviorExtends appended its annotation last, leaving the extends tag at the bottom of the doc-block. Switch to array_unshift so a freshly annotated table renders extends first, followed by the existing property -> method -> mixin sequence (which already matched). The merge path (appendToExistingDocBlock) still appends new tags after the last existing tag, so legacy doc-blocks rely on the sniff fixer for full reordering. Newly generated output is now aligned by construction. Test fixtures under tests/test_files/Model/Table updated to reflect the new order.
When class/interface/trait docblocks have blank " * " separator lines between tag groups, the reordered output preserved them in now-arbitrary positions, splitting newly-coherent same-kind tag groups for no reason. This was caused by getEndIndex() walking back to the previous line without skipping blank docblock lines, so a tag's content range extended through any trailing blank line. The rebuilt content then re-emitted those blanks. Walk back to the actual content (T_DOC_COMMENT_STRING / TAG) instead. Multi-line tag content is unaffected. Adds a fixture that reproduces the case (mirrors a real-world CakePHP table where IDE-helper output had grown over time with blank-line separators).
dereuromark
added a commit
to dereuromark/cakephp-sandbox
that referenced
this pull request
May 9, 2026
Output of phpcbf using DocBlockTagOrder sniff (extended to class / interface / trait docblocks via php-collective/code-sniffer#59) — fully automated, no hand-edits. For Tables and Entities: groups tags as extends -> property -> property-read -> method -> mixin (canonical PHPStan/Psalm class signature first, then state, then magic methods, then late-bound behaviors). For controller test classes: floats the not-in-the-list 'uses' tag to top, leaving 'property' below — matches the sniff's documented 'tags not in the list keep float-to-top behavior'. Within-method order (canonical CRUD ordering, delete cluster matching save cluster shape) is intentionally out of scope here — that requires re-annotating from scratch and is a follow-up.
This was referenced May 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Currently
DocBlockTagOrderonly enforces tag ordering on function/method docblocks. Class-level docblocks — typical example, a CakePHP table where association property tags, ORM method tags, behavior mixin tags, and a generic extends tag accumulate over time as IDE-helpers append output — go unsorted.This PR extends the sniff to also register on
T_CLASS,T_INTERFACE,T_TRAITand adds a separateclassOrderproperty so the class-level order is independent of the function-level one.Default class order
Reasoning:
template/extends/implementsfirst — these declare the class's own type signature (PHPStan/Psalm convention).propertynext — describes class-level state.method— describes magic / dynamically-generated members.mixinlast — additive/late-bound, the class is fully described by the time you read these.Tags not in the list keep the existing "float to top" behavior.
XML configurability
Both
order(function-level, wasprotected, nowpublic) andclassOrder(new) can be overridden:Leading
@on tag names is optional and gets normalized.Tests
DocBlockTagOrderSniffTestis new — there were no existing tests for this sniff. Covers both function-level (regression) and class-level (new) cases plus two configurability variants.