PHP_CodeSniffer
[ class tree: PHP_CodeSniffer ] [ index: PHP_CodeSniffer ] [ all elements ]

Source for file DisallowAlternativePHPTagsSniff.php

Documentation is available at DisallowAlternativePHPTagsSniff.php

  1. <?php
  2. /**
  3.  * Verifies that no alternative PHP tags are used.
  4.  *
  5.  * If alternative PHP open tags are found, this sniff can fix both the open and close tags.
  6.  *
  7.  * @author    Greg Sherwood <gsherwood@squiz.net>
  8.  * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
  9.  * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  10.  */
  11.  
  12. namespace PHP_CodeSniffer\Standards\Generic\Sniffs\PHP;
  13.  
  14. use PHP_CodeSniffer\Sniffs\Sniff;
  15. use PHP_CodeSniffer\Files\File;
  16. use PHP_CodeSniffer\Config;
  17.  
  18. class DisallowAlternativePHPTagsSniff implements Sniff
  19. {
  20.  
  21.     /**
  22.      * Whether ASP tags are enabled or not.
  23.      *
  24.      * @var boolean 
  25.      */
  26.     private $aspTags = false;
  27.  
  28.     /**
  29.      * The current PHP version.
  30.      *
  31.      * @var integer 
  32.      */
  33.     private $phpVersion = null;
  34.  
  35.  
  36.     /**
  37.      * Returns an array of tokens this test wants to listen for.
  38.      *
  39.      * @return array 
  40.      */
  41.     public function register()
  42.     {
  43.         if ($this->phpVersion === null{
  44.             $this->phpVersion = Config::getConfigData('php_version');
  45.             if ($this->phpVersion === null{
  46.                 $this->phpVersion = PHP_VERSION_ID;
  47.             }
  48.         }
  49.  
  50.         if ($this->phpVersion < 70000{
  51.             $this->aspTags = (boolean) ini_get('asp_tags');
  52.         }
  53.  
  54.         return array(
  55.                 T_OPEN_TAG,
  56.                 T_OPEN_TAG_WITH_ECHO,
  57.                 T_INLINE_HTML,
  58.                );
  59.  
  60.     }//end register()
  61.  
  62.  
  63.     /**
  64.      * Processes this test, when one of its tokens is encountered.
  65.      *
  66.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
  67.      * @param int                         $stackPtr  The position of the current token
  68.      *                                                in the stack passed in $tokens.
  69.      *
  70.      * @return void 
  71.      */
  72.     public function process(File $phpcsFile$stackPtr)
  73.     {
  74.         $tokens  $phpcsFile->getTokens();
  75.         $openTag $tokens[$stackPtr];
  76.         $content $openTag['content'];
  77.  
  78.         if (trim($content=== ''{
  79.             return;
  80.         }
  81.  
  82.         if ($openTag['code'=== T_OPEN_TAG{
  83.             if ($content === '<%'{
  84.                 $error     'ASP style opening tag used; expected "<?php" but found "%s"';
  85.                 $closer    $this->findClosingTag($phpcsFile$tokens$stackPtr'%>');
  86.                 $errorCode 'ASPOpenTagFound';
  87.             else if (strpos($content'<script '!== false{
  88.                 $error     'Script style opening tag used; expected "<?php" but found "%s"';
  89.                 $closer    $this->findClosingTag($phpcsFile$tokens$stackPtr'</script>');
  90.                 $errorCode 'ScriptOpenTagFound';
  91.             }
  92.  
  93.             if (isset($error$closer$errorCode=== true{
  94.                 $data = array($content);
  95.  
  96.                 if ($closer === false{
  97.                     $phpcsFile->addError($error$stackPtr$errorCode$data);
  98.                 else {
  99.                     $fix $phpcsFile->addFixableError($error$stackPtr$errorCode$data);
  100.                     if ($fix === true{
  101.                         $this->addChangeset($phpcsFile$tokens$stackPtr$closer);
  102.                     }
  103.                 }
  104.             }
  105.  
  106.             return;
  107.         }//end if
  108.  
  109.         if ($openTag['code'=== T_OPEN_TAG_WITH_ECHO && $content === '<%='{
  110.             $error   'ASP style opening tag used with echo; expected "<?php echo %s ..." but found "%s %s ..."';
  111.             $nextVar $phpcsFile->findNext(T_WHITESPACE($stackPtr + 1)nulltrue);
  112.             $snippet $this->getSnippet($tokens[$nextVar]['content']);
  113.             $data    = array(
  114.                         $snippet,
  115.                         $content,
  116.                         $snippet,
  117.                        );
  118.  
  119.             $closer $this->findClosingTag($phpcsFile$tokens$stackPtr'%>');
  120.  
  121.             if ($closer === false{
  122.                 $phpcsFile->addError($error$stackPtr'ASPShortOpenTagFound'$data);
  123.             else {
  124.                 $fix $phpcsFile->addFixableError($error$stackPtr'ASPShortOpenTagFound'$data);
  125.                 if ($fix === true{
  126.                     $this->addChangeset($phpcsFile$tokens$stackPtr$closertrue);
  127.                 }
  128.             }
  129.  
  130.             return;
  131.         }//end if
  132.  
  133.         // Account for incorrect script open tags.
  134.         // The "(?:<s)?" in the regex is to work-around a bug in PHP 5.2.
  135.         if ($openTag['code'=== T_INLINE_HTML
  136.             && preg_match('`((?:<s)?cript (?:[^>]+)?language=[\'"]?php[\'"]?(?:[^>]+)?>)`i'$content$match=== 1
  137.         {
  138.             $error   'Script style opening tag used; expected "<?php" but found "%s"';
  139.             $snippet $this->getSnippet($content$match[1]);
  140.             $data    = array($match[1].$snippet);
  141.  
  142.             $phpcsFile->addError($error$stackPtr'ScriptOpenTagFound'$data);
  143.             return;
  144.         }
  145.  
  146.         if ($openTag['code'=== T_INLINE_HTML && $this->aspTags === false{
  147.             if (strpos($content'<%='!== false{
  148.                 $error   'Possible use of ASP style short opening tags detected; found: %s';
  149.                 $snippet $this->getSnippet($content'<%=');
  150.                 $data    = array('<%='.$snippet);
  151.  
  152.                 $phpcsFile->addWarning($error$stackPtr'MaybeASPShortOpenTagFound'$data);
  153.             else if (strpos($content'<%'!== false{
  154.                 $error   'Possible use of ASP style opening tags detected; found: %s';
  155.                 $snippet $this->getSnippet($content'<%');
  156.                 $data    = array('<%'.$snippet);
  157.  
  158.                 $phpcsFile->addWarning($error$stackPtr'MaybeASPOpenTagFound'$data);
  159.             }
  160.         }
  161.  
  162.     }//end process()
  163.  
  164.  
  165.     /**
  166.      * Get a snippet from a HTML token.
  167.      *
  168.      * @param string $content The content of the HTML token.
  169.      * @param string $start   Partial string to use as a starting point for the snippet.
  170.      * @param int    $length  The target length of the snippet to get. Defaults to 40.
  171.      *
  172.      * @return string 
  173.      */
  174.     protected function getSnippet($content$start=''$length=40)
  175.     {
  176.         $startPos = 0;
  177.  
  178.         if ($start !== ''{
  179.             $startPos strpos($content$start);
  180.             if ($startPos !== false{
  181.                 $startPos += strlen($start);
  182.             }
  183.         }
  184.  
  185.         $snippet substr($content$startPos$length);
  186.         if ((strlen($content$startPos$length{
  187.             $snippet .= '...';
  188.         }
  189.  
  190.         return $snippet;
  191.  
  192.     }//end getSnippet()
  193.  
  194.  
  195.     /**
  196.      * Try and find a matching PHP closing tag.
  197.      *
  198.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
  199.      * @param array                       $tokens    The token stack.
  200.      * @param int                         $stackPtr  The position of the current token
  201.      *                                                in the stack passed in $tokens.
  202.      * @param string                      $content   The expected content of the closing tag to match the opener.
  203.      *
  204.      * @return int|falsePointer to the position in the stack for the closing tag or false if not found.
  205.      */
  206.     protected function findClosingTag(File $phpcsFile$tokens$stackPtr$content)
  207.     {
  208.         $closer $phpcsFile->findNext(T_CLOSE_TAG($stackPtr + 1));
  209.  
  210.         if ($closer !== false && $content === trim($tokens[$closer]['content'])) {
  211.             return $closer;
  212.         }
  213.  
  214.         return false;
  215.  
  216.     }//end findClosingTag()
  217.  
  218.  
  219.     /**
  220.      * Add a changeset to replace the alternative PHP tags.
  221.      *
  222.      * @param \PHP_CodeSniffer\Files\File $phpcsFile       The file being scanned.
  223.      * @param array                       $tokens          The token stack.
  224.      * @param int                         $openTagPointer  Stack pointer to the PHP open tag.
  225.      * @param int                         $closeTagPointer Stack pointer to the PHP close tag.
  226.      * @param bool                        $echo            Whether to add 'echo' or not.
  227.      *
  228.      * @return void 
  229.      */
  230.     protected function addChangeset(File $phpcsFile$tokens$openTagPointer$closeTagPointer$echo=false)
  231.     {
  232.         // Build up the open tag replacement and make sure there's always whitespace behind it.
  233.         $openReplacement '<?php';
  234.         if ($echo === true{
  235.             $openReplacement .= ' echo';
  236.         }
  237.  
  238.         if ($tokens[($openTagPointer + 1)]['code'!== T_WHITESPACE{
  239.             $openReplacement .= ' ';
  240.         }
  241.  
  242.         // Make sure we don't remove any line breaks after the closing tag.
  243.         $regex            '`'.preg_quote(trim($tokens[$closeTagPointer]['content'])).'`';
  244.         $closeReplacement preg_replace($regex'?>'$tokens[$closeTagPointer]['content']);
  245.  
  246.         $phpcsFile->fixer->beginChangeset();
  247.         $phpcsFile->fixer->replaceToken($openTagPointer$openReplacement);
  248.         $phpcsFile->fixer->replaceToken($closeTagPointer$closeReplacement);
  249.         $phpcsFile->fixer->endChangeset();
  250.  
  251.     }//end addChangeset()
  252.  
  253.  
  254. }//end class

Documentation generated on Mon, 11 Mar 2019 15:27:22 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.