ConstantUsageSniff.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sniffs\Translation;
  7. use PHP_CodeSniffer\Files\File;
  8. use PHP_CodeSniffer\Sniffs\Sniff;
  9. /**
  10. * Make sure that constants are not used as the first argument of translation function.
  11. */
  12. class ConstantUsageSniff implements Sniff
  13. {
  14. /**
  15. * Having previous line content allows to process multi-line declaration.
  16. *
  17. * @var string
  18. */
  19. protected $previousLineContent = '';
  20. /**
  21. * @inheritdoc
  22. */
  23. public function register()
  24. {
  25. return [T_OPEN_TAG];
  26. }
  27. /**
  28. * Copied from \Generic_Sniffs_Files_LineLengthSniff, minor changes made
  29. *
  30. * {@inheritdoc}
  31. *
  32. * @param \PHP_CodeSniffer\Files\File $phpcsFile
  33. * @param int $stackPtr
  34. * @return void|int
  35. */
  36. public function process(File $phpcsFile, $stackPtr)
  37. {
  38. $tokens = $phpcsFile->getTokens();
  39. // Make sure this is the first open tag
  40. $previousOpenTag = $phpcsFile->findPrevious(T_OPEN_TAG, ($stackPtr - 1));
  41. if ($previousOpenTag !== false) {
  42. return;
  43. }
  44. $tokenCount = 0;
  45. $currentLineContent = '';
  46. $currentLine = 1;
  47. for (; $tokenCount < $phpcsFile->numTokens; $tokenCount++) {
  48. if ($tokens[$tokenCount]['line'] === $currentLine) {
  49. $currentLineContent .= $tokens[$tokenCount]['content'];
  50. } else {
  51. $this->checkIfFirstArgumentConstant($phpcsFile, ($tokenCount - 1), $currentLineContent);
  52. $currentLineContent = $tokens[$tokenCount]['content'];
  53. $currentLine++;
  54. }
  55. }
  56. $this->checkIfFirstArgumentConstant($phpcsFile, ($tokenCount - 1), $currentLineContent);
  57. }
  58. /**
  59. * Checks if first argument of \Magento\Framework\Phrase or translation function is a constant
  60. *
  61. * @param File $phpcsFile
  62. * @param int $stackPtr
  63. * @param string $lineContent
  64. * @return void
  65. */
  66. private function checkIfFirstArgumentConstant(
  67. File $phpcsFile,
  68. $stackPtr,
  69. $lineContent
  70. ) {
  71. $previousLineRegexp = '/(__|Phrase)\($/im';
  72. $currentLineRegexp = '/(__|Phrase)\(.+\)/';
  73. $currentLineMatch = preg_match($currentLineRegexp, $lineContent) !== 0;
  74. $previousLineMatch = preg_match($previousLineRegexp, $this->previousLineContent) !== 0;
  75. $this->previousLineContent = $lineContent;
  76. $error = 'Constants are not allowed as the first argument of translation function, use string literal instead';
  77. $constantRegexp = '[^\$\'"]+::[A-Z_0-9]+.*';
  78. if ($currentLineMatch) {
  79. $variableRegexp = "/(__|Phrase)\({$constantRegexp}\)/";
  80. if (preg_match($variableRegexp, $lineContent) !== 0) {
  81. $phpcsFile->addError($error, $stackPtr, 'VariableTranslation');
  82. }
  83. } elseif ($previousLineMatch) {
  84. $variableRegexp = "/^{$constantRegexp}/";
  85. if (preg_match($variableRegexp, $lineContent) !== 0) {
  86. $phpcsFile->addError($error, $stackPtr, 'VariableTranslation');
  87. }
  88. }
  89. }
  90. }