WordPress-Coding-Standards
WordPress-Coding-Standards copied to clipboard
WP-Core produces inconsistent indentation
Bug Description
WP-Core produces inconsistent indentation
https://github.com/user-attachments/assets/04e12f56-7e91-4ac7-b516-8ba7a203f777
Minimal Code Snippet
<div
<?php
if ( false ) {
echo 'class="hi"';
}
?>
></div>
Running with WordPress-Core standard in phpcs / phpcbf
Error Code
N/A
Environment
php -v PHP 8.1.10 (cli) (built: Aug 30 2022 18:08:04) (NTS Visual C++ 2019 x64) Copyright (c) The PHP Group Zend Engine v4.1.10, Copyright (c) Zend Technologies
composer info
dealerdirect/phpcodesniffer-composer-installer contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins
Do you trust "dealerdirect/phpcodesniffer-composer-installer" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?] y
clue/ndjson-react v1.3.0 Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.
composer/pcre 3.3.2 PCRE wrapping library that offers type-safe preg_* replacements.
composer/semver 3.4.3 Semver library that offers utilities, version constraint parsing and validation.
composer/xdebug-handler 3.0.5 Restarts a process without Xdebug.
dealerdirect/phpcodesniffer-composer-installer v1.0.0 PHP_CodeSniffer Standards Composer Installer Plugin
evenement/evenement v3.0.2 Événement is a very simple event dispatching library for PHP
fidry/cpu-core-counter 1.2.0 Tiny utility to get the number of CPU cores.
friendsofphp/php-cs-fixer v3.72.0 A tool to automatically fix PHP code style
php-stubs/acf-pro-stubs v6.0.6 Advanced Custom Fields PRO stubs for static analysis.
php-stubs/wordpress-stubs v6.2.0 WordPress function and class declaration stubs for static analysis.
phpcompatibility/php-compatibility 9.3.5 A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.
phpcompatibility/phpcompatibility-paragonie 1.3.3 A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while acco...
phpcompatibility/phpcompatibility-wp 2.1.6 A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting f...
phpcsstandards/phpcsextra 1.2.1 A collection of sniffs and standards for use with PHP_CodeSniffer.
phpcsstandards/phpcsutils 1.0.12 A suite of utility functions for use with PHP_CodeSniffer
psr/container 2.0.2 Common Container Interface (PHP FIG PSR-11)
psr/event-dispatcher 1.0.0 Standard interfaces for event handling.
psr/log 3.0.2 Common interface for logging libraries
react/cache v1.2.0 Async, Promise-based cache interface for ReactPHP
react/child-process v0.6.6 Event-driven library for executing child processes with ReactPHP.
react/dns v1.13.0 Async DNS resolver for ReactPHP
react/event-loop v1.5.0 ReactPHP's core reactor event loop that libraries can use for evented I/O.
react/promise v3.2.0 A lightweight implementation of CommonJS Promises/A for PHP
react/socket v1.16.0 Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP
react/stream v1.4.0 Event-driven readable and writable streams for non-blocking I/O in ReactPHP
sebastian/diff 5.1.1 Diff implementation
squizlabs/php_codesniffer 3.11.3 PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.
symfony/console v6.4.17 Eases the creation of beautiful and testable command line interfaces
symfony/deprecation-contracts v3.5.1 A generic function and convention to trigger deprecation notices
symfony/event-dispatcher v6.4.13 Provides tools that allow your application components to communicate with each other by dispatching events and li...
symfony/event-dispatcher-contracts v3.5.1 Generic abstractions related to dispatching event
symfony/filesystem v6.4.13 Provides basic utilities for the filesystem
symfony/finder v6.4.17 Finds files and directories via an intuitive fluent interface
symfony/options-resolver v6.4.16 Provides an improved replacement for the array_replace PHP function
symfony/polyfill-ctype v1.31.0 Symfony polyfill for ctype functions
symfony/polyfill-intl-grapheme v1.31.0 Symfony polyfill for intl's grapheme_* functions
symfony/polyfill-intl-normalizer v1.31.0 Symfony polyfill for intl's Normalizer class and related functions
symfony/polyfill-mbstring v1.31.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php80 v1.31.0 Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions
symfony/polyfill-php81 v1.31.0 Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions
symfony/process v6.4.19 Executes commands in sub-processes
symfony/service-contracts v3.5.1 Generic abstractions related to writing services
symfony/stopwatch v6.4.19 Provides a way to profile code
symfony/string v6.4.15 Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a uni...
wp-coding-standards/wpcs 3.1.0 PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions
VS Code
@justingolden21 Not sure what you are trying to report. The video doesn't play and if I run the WordPress-Core standard against the provided code sample, there are "no violations found".
In other words, this is not reproducible and this issue will be closed unless a proper reproduction sample is provided.
@justingolden21 is this issue related to the linter extension you are using in your editor? If so, that is out of scope of this repo.
@jrfnl thank you for the quick reply. The video does play on my end, so I'm not sure about video playing issues, if it's a file format/browser thing or what. It's an mp4 file. The video demonstrates that there is no one indentation standard being applied, and that depending on what level I indent certain lines, I get different results. Also, those results are not only inconsistent, but provide significantly too many tabs.
Example:
The following line:
<div id="<?php echo $fields['id']; ?>" <?php if (!empty($fields['screen_height_placeholder']) && $fields['screen_height_placeholder']) echo 'class="min-h-screen overflow-y-auto"'; ?>></div>
Becomes formatted to:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
With five and six tabs of indentation.
Upon changing to:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
It formats to:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
Upon changing to:
<div id="<?php echo $fields['id']; ?>" <?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
It formats to:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
Upon changing to:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
It produces no changes.
Upon changing to:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
It formats to:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
Upon changing to:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
It produces no change.
Upon changing to:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
It changes to:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
These are a few examples of how the initial condition produces widely different results, and these results exhibit very poor and incorrect indentation. I would personally consider this a bug.
Thanks again for the reply, and let me know if I'm opening an issue in the wrong place.
I am using phpcs with "WordPress-Core" as the standard. So I'm using a linter, but it is following the coding standards defined here without any modification to the standards whatsoever.
Another minimal reproducible example:
<div class="contents <?php if(!empty($post_description)) { echo 'opacity-100 lg:group-hover:opacity-0 transition-opacity'; } ?>">
</div>
Gets formatted to:
<div class="contents <?php if (!empty($post_description)) {
echo 'opacity-100 lg:group-hover:opacity-0 transition-opacity';
} ?>">
</div>
With six and seven indentation levels more.
With the second provided snippet in my phpcs-test.php file:
<div id="<?php echo $fields['id']; ?>" <?php if (!empty($fields['screen_height_placeholder']) && $fields['screen_height_placeholder']) echo 'class="min-h-screen overflow-y-auto"'; ?>></div>
when I run phpcs -s --standard=WordPress-Core phpcs-test.php, I get:
1 | ERROR | [x] Inline control structures are not allowed (Generic.ControlStructures.InlineControlStructure.NotAllowed)
1 | ERROR | [x] Expected 1 space before "!"; 0 found (WordPress.WhiteSpace.OperatorSpacing.NoSpaceBefore)
1 | ERROR | [x] Expected 1 space after "!"; 0 found (WordPress.WhiteSpace.OperatorSpacing.NoSpaceAfter)
1 | ERROR | [x] Expected 1 spaces after opening parenthesis; 0 found (PEAR.Functions.FunctionCallSignature.SpaceAfterOpenBracket)
1 | ERROR | [x] Expected 1 spaces before closing parenthesis; 0 found (PEAR.Functions.FunctionCallSignature.SpaceBeforeCloseBracket)
When I run phpcbf --standard=WordPress-Core phpcs-test.php, I get the five issues fixed, and file contents of:
<div id="<?php echo $fields['id']; ?>"
<?php
if ( ! empty( $fields['screen_height_placeholder'] ) && $fields['screen_height_placeholder'] ) {
echo 'class="min-h-screen overflow-y-auto"';}
?>
></div>
That's 5 tabs before the second PHP delimiter.
If I run it again, I get no change.