diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidConstantNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidConstantNameSniff.php
new file mode 100644
index 0000000..a08b3c2
--- /dev/null
+++ b/src/Cdn77/Sniffs/NamingConventions/ValidConstantNameSniff.php
@@ -0,0 +1,142 @@
+
+ */
+ public function register(): array
+ {
+ return [
+ T_STRING,
+ T_CONST,
+ ];
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack passed in $tokens.
+ *
+ * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
+ */
+ public function process(File $phpcsFile, $stackPtr): void
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if ($tokens[$stackPtr]['code'] === T_CONST) {
+ // This is a class constant.
+ $constant = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true);
+ if ($constant === false) {
+ return;
+ }
+
+ $constName = $tokens[$constant]['content'];
+
+ if ($this->matchesRegex($constName, $this->pattern)) {
+ return;
+ }
+
+ $error = sprintf('Constant "%%s" does not match pattern "%s"', $this->pattern);
+ $data = [$constName];
+ $phpcsFile->addError(
+ $error,
+ $constant,
+ self::CodeClassConstantNotMatchPattern,
+ $data,
+ );
+ }
+
+ // Only interested in define statements now.
+ if (strtolower($tokens[$stackPtr]['content']) !== 'define') {
+ return;
+ }
+
+ // Make sure this is not a method call.
+ $prev = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true);
+ if (
+ $tokens[$prev]['code'] === T_OBJECT_OPERATOR
+ || $tokens[$prev]['code'] === T_DOUBLE_COLON
+ || $tokens[$prev]['code'] === T_NULLSAFE_OBJECT_OPERATOR
+ ) {
+ return;
+ }
+
+ // If the next non-whitespace token after this token
+ // is not an opening parenthesis then it is not a function call.
+ $openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true);
+ if ($openBracket === false) {
+ return;
+ }
+
+ // The next non-whitespace token must be the constant name.
+ $constPtr = $phpcsFile->findNext(T_WHITESPACE, $openBracket + 1, null, true);
+ if ($tokens[$constPtr]['code'] !== T_CONSTANT_ENCAPSED_STRING) {
+ return;
+ }
+
+ $constName = $tokens[$constPtr]['content'];
+
+ // Check for constants like self::CONSTANT.
+ $prefix = '';
+ $splitPos = strpos($constName, '::');
+ if ($splitPos !== false) {
+ $prefix = substr($constName, 0, $splitPos + 2);
+ $constName = substr($constName, $splitPos + 2);
+ }
+
+ // Strip namespace from constant like /foo/bar/CONSTANT.
+ $splitPos = strrpos($constName, '\\');
+ if ($splitPos !== false) {
+ $prefix = substr($constName, 0, $splitPos + 1);
+ $constName = substr($constName, $splitPos + 1);
+ }
+
+ if ($this->matchesRegex($constName, $this->pattern)) {
+ return;
+ }
+
+ $error = sprintf('Constant "%%s" does not match pattern "%s"', $this->pattern);
+ $data = [
+ $prefix . $constName,
+ ];
+ $phpcsFile->addError($error, $stackPtr, self::CodeConstantNotMatchPattern, $data);
+ }
+
+ private function matchesRegex(string $varName, string $pattern): bool
+ {
+ return preg_match(sprintf('~%s~', $pattern), $varName) === 1;
+ }
+}
diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php
index 436a4ce..6133500 100644
--- a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php
+++ b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php
@@ -22,15 +22,15 @@
class ValidVariableNameSniff extends AbstractVariableSniff
{
- public const CODE_DOES_NOT_MATCH_PATTERN = 'DoesNotMatchPattern';
- public const CODE_MEMBER_DOES_NOT_MATCH_PATTERN = 'MemberDoesNotMatchPattern';
- public const CODE_STRING_DOES_NOT_MATCH_PATTERN = 'StringDoesNotMatchPattern';
- private const PATTERN_CAMEL_CASE = '\b([a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?)\b';
- private const PATTERN_CAMEL_CASE_OR_UNUSED = '\b(([a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?)|_+)\b';
+ public const CodeDoesNotMatchPattern = 'DoesNotMatchPattern';
+ public const CodeMemberDoesNotMatchPattern = 'MemberDoesNotMatchPattern';
+ public const CodeStringDoesNotMatchPattern = 'StringDoesNotMatchPattern';
+ private const PatternCamelCase = '\b([a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?)\b';
+ private const PatternCamelCaseOrUnused = '\b(([a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?)|_+)\b';
- public string $pattern = self::PATTERN_CAMEL_CASE_OR_UNUSED;
- public string $memberPattern = self::PATTERN_CAMEL_CASE;
- public string $stringPattern = self::PATTERN_CAMEL_CASE;
+ public string $pattern = self::PatternCamelCaseOrUnused;
+ public string $memberPattern = self::PatternCamelCase;
+ public string $stringPattern = self::PatternCamelCase;
/**
* Processes this test, when one of its tokens is encountered.
@@ -69,7 +69,7 @@ protected function processVariable(File $phpcsFile, $stackPtr): void
if (! $this->matchesRegex($objVarName, $this->memberPattern)) {
$error = sprintf('Member variable "%%s" does not match pattern "%s"', $this->memberPattern);
$data = [$objVarName];
- $phpcsFile->addError($error, $var, self::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, $data);
+ $phpcsFile->addError($error, $var, self::CodeMemberDoesNotMatchPattern, $data);
}
}
}
@@ -80,7 +80,7 @@ protected function processVariable(File $phpcsFile, $stackPtr): void
if (! $this->matchesRegex($varName, $this->memberPattern)) {
$error = sprintf('Member variable "%%s" does not match pattern "%s"', $this->memberPattern);
$data = [$tokens[$stackPtr]['content']];
- $phpcsFile->addError($error, $stackPtr, self::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, $data);
+ $phpcsFile->addError($error, $stackPtr, self::CodeMemberDoesNotMatchPattern, $data);
}
return;
@@ -92,7 +92,7 @@ protected function processVariable(File $phpcsFile, $stackPtr): void
$error = sprintf('Variable "%%s" does not match pattern "%s"', $this->pattern);
$data = [$varName];
- $phpcsFile->addError($error, $stackPtr, self::CODE_DOES_NOT_MATCH_PATTERN, $data);
+ $phpcsFile->addError($error, $stackPtr, self::CodeDoesNotMatchPattern, $data);
}
/**
@@ -124,7 +124,7 @@ protected function processMemberVar(File $phpcsFile, $stackPtr): void
}
$error = sprintf('Member variable "%%s" does not match pattern "%s"', $this->memberPattern);
- $phpcsFile->addError($error, $stackPtr, self::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, $errorData);
+ $phpcsFile->addError($error, $stackPtr, self::CodeMemberDoesNotMatchPattern, $errorData);
}
/**
@@ -161,7 +161,7 @@ protected function processVariableInString(File $phpcsFile, $stackPtr): void
$error = sprintf('Variable "%%s" does not match pattern "%s"', $this->stringPattern);
$data = [$varName];
- $phpcsFile->addError($error, $stackPtr, self::CODE_STRING_DOES_NOT_MATCH_PATTERN, $data);
+ $phpcsFile->addError($error, $stackPtr, self::CodeStringDoesNotMatchPattern, $data);
}
}
diff --git a/src/Cdn77/ruleset.xml b/src/Cdn77/ruleset.xml
index a932fda..b9ece02 100644
--- a/src/Cdn77/ruleset.xml
+++ b/src/Cdn77/ruleset.xml
@@ -26,6 +26,9 @@
+
+
+
@@ -39,6 +42,7 @@
+
diff --git a/tests/Sniffs/NamingConventions/ValidConstantNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidConstantNameSniffTest.php
new file mode 100644
index 0000000..e652cc0
--- /dev/null
+++ b/tests/Sniffs/NamingConventions/ValidConstantNameSniffTest.php
@@ -0,0 +1,42 @@
+ ValidConstantNameSniff::CodeConstantNotMatchPattern,
+ 8 => ValidConstantNameSniff::CodeConstantNotMatchPattern,
+ 10 => ValidConstantNameSniff::CodeConstantNotMatchPattern,
+ 11 => ValidConstantNameSniff::CodeConstantNotMatchPattern,
+ 17 => ValidConstantNameSniff::CodeClassConstantNotMatchPattern,
+ 18 => ValidConstantNameSniff::CodeClassConstantNotMatchPattern,
+ 19 => ValidConstantNameSniff::CodeClassConstantNotMatchPattern,
+ ];
+ $possibleLines = array_keys($errorTypesPerLine);
+
+ $errors = $file->getErrors();
+ foreach ($errors as $line => $error) {
+ self::assertContains($line, $possibleLines, json_encode($error, JSON_THROW_ON_ERROR));
+
+ $errorType = $errorTypesPerLine[$line];
+
+ self::assertSniffError($file, $line, $errorType);
+ }
+
+ self::assertSame(6, $file->getErrorCount());
+ }
+}
diff --git a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php
index 440e92c..ee71629 100644
--- a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php
+++ b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php
@@ -19,47 +19,47 @@ public function testErrors(): void
$file = self::checkFile(__DIR__ . '/data/ValidVariableNameSniffTest.inc');
$errorTypesPerLine = [
- 3 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 5 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 10 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 12 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 15 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 17 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 19 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 20 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 21 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 26 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 28 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 31 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN,
- 32 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN,
- 34 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN,
- 37 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 39 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 48 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 50 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 53 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 55 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 57 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 58 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 59 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 62 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 76 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN,
- 100 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 101 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 102 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 117 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 118 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 128 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 132 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 134 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 135 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- 140 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
- 142 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN,
+ 3 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 5 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 10 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 12 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 15 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 17 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 19 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 20 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 21 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 26 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 28 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 31 => ValidVariableNameSniff::CodeStringDoesNotMatchPattern,
+ 32 => ValidVariableNameSniff::CodeStringDoesNotMatchPattern,
+ 34 => ValidVariableNameSniff::CodeStringDoesNotMatchPattern,
+ 37 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 39 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 48 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 50 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 53 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 55 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 57 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 58 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 59 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 62 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 76 => ValidVariableNameSniff::CodeStringDoesNotMatchPattern,
+ 100 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 101 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 102 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 117 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 118 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 128 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 132 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 134 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 135 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ 140 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
+ 142 => ValidVariableNameSniff::CodeMemberDoesNotMatchPattern,
144 => [
- ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
- ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
+ ValidVariableNameSniff::CodeDoesNotMatchPattern,
+ ValidVariableNameSniff::CodeDoesNotMatchPattern,
],
- 146 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN,
+ 146 => ValidVariableNameSniff::CodeDoesNotMatchPattern,
];
$possibleLines = array_keys($errorTypesPerLine);
diff --git a/tests/Sniffs/NamingConventions/data/ValidConstantNameTest.inc b/tests/Sniffs/NamingConventions/data/ValidConstantNameTest.inc
new file mode 100644
index 0000000..a8a3ae8
--- /dev/null
+++ b/tests/Sniffs/NamingConventions/data/ValidConstantNameTest.inc
@@ -0,0 +1,24 @@
+define('bar');
+$foo->getBar()->define('foo');
+Foo::define('bar');