Home » Php » emacs – How to configure PHP CodeSniffer to allow my case statements to be indented the way I like?

emacs – How to configure PHP CodeSniffer to allow my case statements to be indented the way I like?

Posted by: admin July 12, 2020 Leave a comment

Questions:

I have code that looks like this:

function processRequest() {

  // get the verb
  $method = strtolower($_SERVER['REQUEST_METHOD']);

  switch ($method) {
    case 'get':
      handleGet();
      break;
    case 'post':
      handlePost();
      // $data = $_POST;
      break;
    case 'delete':
      handleDelete();
      break;
    case 'options':
      header('Allow: GET, POST, DELETE, OPTIONS');
      break;
    default:
      header('HTTP/1.1 405 Method Not Allowed');
      break;
  }
}

PHP CodeSniffer complains about the indents of those case statements. In emacs with flymake it looks like this:

enter image description here

The message is:

error – Line indented incorrectly; expected 2 spaces, found 4 (PEAR.WhiteSpace.ScopeIndent.Incorrect)

Obviously CodeSniffer wants the case statements to be LESS indented than they are.

How can I tell CodeSniffer to allow my case statements to be indented the way I want them. Or better, to enforce that my case statements are indented this way?

How to&Answers:

The Sniff known as PEAR.Whitespace.ScopeIndent is defined in code file phpcs\CodeSniffer\Standards\PEAR\Sniffs\Whitespace\ScopeIndentSniff.php and includes the following code:

class PEAR_Sniffs_WhiteSpace_ScopeIndentSniff extends Generic_Sniffs_WhiteSpace_ScopeIndentSniff
{
    /**
     * Any scope openers that should not cause an indent.
     *
     * @var array(int)
     */
    protected $nonIndentingScopes = array(T_SWITCH);

}//end class

See the $nonIndentingScopes? It apparently means that anything within the scope of a switch statement is expected to not be indented with respect to the scope-opening curly.

I could not find a way to tweak this setting in PEAR.Whitespace.ScopeIndent, but…. that Sniff extends the more basic Generic.Whitespace.ScopeIndent, which does not include T_SWITCH in the $nonIndentingScopes array.

So what I did to allow my case statements the way I wanted was to modify my ruleset.xml file, to exclude the PEAR version of that sniff, and include the Generic version of that sniff. It looks like this:

<?xml version="1.0"?>
<ruleset name="Custom Standard">
  <!-- http://pear.php.net/manual/en/package.php.php-codesniffer.annotated-ruleset.php -->
  <description>My custom coding standard</description>

  <rule ref="PEAR">
         ......
    <exclude name="PEAR.WhiteSpace.ScopeIndent"/>
  </rule>

   ....

  <!-- not PEAR -->
  <rule ref="Generic.WhiteSpace.ScopeIndent">
    <properties>
      <property name="indent" value="2"/>
    </properties>
  </rule>

</ruleset>

This file needs to be present in a subdir under the Standards directory for PHP CodeSniffer. For me, the file location is \dev\phpcs\CodeSniffer\Standards\MyStandard\ruleset.xml

Then I run phpcs like this:

\php\php.exe \dev\phpcs\scripts\phpcs --standard=MyStandard --report=emacs -s file.php