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

Source for file Common.php

Documentation is available at Common.php

  1. <?php
  2. /**
  3.  * Basic util functions.
  4.  *
  5.  * @author    Greg Sherwood <gsherwood@squiz.net>
  6.  * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
  7.  * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  8.  */
  9.  
  10. namespace PHP_CodeSniffer\Util;
  11.  
  12. use PHP_CodeSniffer\Config;
  13. use PHP_CodeSniffer\Exceptions\RuntimeException;
  14.  
  15. class Common
  16. {
  17.  
  18.     /**
  19.      * An array of variable types for param/var we will check.
  20.      *
  21.      * @var string[] 
  22.      */
  23.     public static $allowedTypes = array(
  24.                                    'array',
  25.                                    'boolean',
  26.                                    'float',
  27.                                    'integer',
  28.                                    'mixed',
  29.                                    'object',
  30.                                    'string',
  31.                                    'resource',
  32.                                    'callable',
  33.                                   );
  34.  
  35.  
  36.     /**
  37.      * Return TRUE if the path is a PHAR file.
  38.      *
  39.      * @param string $path The path to use.
  40.      *
  41.      * @return mixed 
  42.      */
  43.     public static function isPharFile($path)
  44.     {
  45.         if (strpos($path'phar://'=== 0{
  46.             return true;
  47.         }
  48.  
  49.         return false;
  50.  
  51.     }//end isPharFile()
  52.  
  53.  
  54.     /**
  55.      * CodeSniffer alternative for realpath.
  56.      *
  57.      * Allows for PHAR support.
  58.      *
  59.      * @param string $path The path to use.
  60.      *
  61.      * @return mixed 
  62.      */
  63.     public static function realpath($path)
  64.     {
  65.         // Support the path replacement of ~ with the user's home directory.
  66.         if (substr($path02=== '~/'{
  67.             $homeDir getenv('HOME');
  68.             if ($homeDir !== false{
  69.                 $path $homeDir.substr($path1);
  70.             }
  71.         }
  72.  
  73.         // No extra work needed if this is not a phar file.
  74.         if (self::isPharFile($path=== false{
  75.             return realpath($path);
  76.         }
  77.  
  78.         // Before trying to break down the file path,
  79.         // check if it exists first because it will mostly not
  80.         // change after running the below code.
  81.         if (file_exists($path=== true{
  82.             return $path;
  83.         }
  84.  
  85.         $phar  = \Phar::running(false);
  86.         $extra str_replace('phar://'.$phar''$path);
  87.         $path  realpath($phar);
  88.         if ($path === false{
  89.             return false;
  90.         }
  91.  
  92.         $path 'phar://'.$path.$extra;
  93.         if (file_exists($path=== true{
  94.             return $path;
  95.         }
  96.  
  97.         return false;
  98.  
  99.     }//end realpath()
  100.  
  101.  
  102.     /**
  103.      * Removes a base path from the front of a file path.
  104.      *
  105.      * @param string $path     The path of the file.
  106.      * @param string $basepath The base path to remove. This should not end
  107.      *                          with a directory separator.
  108.      *
  109.      * @return string 
  110.      */
  111.     public static function stripBasepath($path$basepath)
  112.     {
  113.         if (empty($basepath=== true{
  114.             return $path;
  115.         }
  116.  
  117.         $basepathLen strlen($basepath);
  118.         if (substr($path0$basepathLen=== $basepath{
  119.             $path substr($path$basepathLen);
  120.         }
  121.  
  122.         $path ltrim($pathDIRECTORY_SEPARATOR);
  123.         if ($path === ''{
  124.             $path '.';
  125.         }
  126.  
  127.         return $path;
  128.  
  129.     }//end stripBasepath()
  130.  
  131.  
  132.     /**
  133.      * Detects the EOL character being used in a string.
  134.      *
  135.      * @param string $contents The contents to check.
  136.      *
  137.      * @return string 
  138.      */
  139.     public static function detectLineEndings($contents)
  140.     {
  141.         if (preg_match("/\r\n?|\n/"$contents$matches!== 1{
  142.             // Assume there are no newlines.
  143.             $eolChar "\n";
  144.         else {
  145.             $eolChar $matches[0];
  146.         }
  147.  
  148.         return $eolChar;
  149.  
  150.     }//end detectLineEndings()
  151.  
  152.  
  153.     /**
  154.      * Prepares token content for output to screen.
  155.      *
  156.      * Replaces invisible characters so they are visible. On non-Windows
  157.      * OSes it will also colour the invisible characters.
  158.      *
  159.      * @param string   $content The content to prepare.
  160.      * @param string[] $exclude A list of characters to leave invisible.
  161.      *                           Can contain \r, \n, \t and a space.
  162.      *
  163.      * @return string 
  164.      */
  165.     public static function prepareForOutput($content$exclude=array())
  166.     {
  167.         if (strtoupper(substr(PHP_OS03)) === 'WIN'{
  168.             if (in_array("\r"$exclude=== false{
  169.                 $content str_replace("\r"'\r'$content);
  170.             }
  171.  
  172.             if (in_array("\n"$exclude=== false{
  173.                 $content str_replace("\n"'\n'$content);
  174.             }
  175.  
  176.             if (in_array("\t"$exclude=== false{
  177.                 $content str_replace("\t"'\t'$content);
  178.             }
  179.         else {
  180.             if (in_array("\r"$exclude=== false{
  181.                 $content str_replace("\r""\033[30;1m\\r\033[0m"$content);
  182.             }
  183.  
  184.             if (in_array("\n"$exclude=== false{
  185.                 $content str_replace("\n""\033[30;1m\\n\033[0m"$content);
  186.             }
  187.  
  188.             if (in_array("\t"$exclude=== false{
  189.                 $content str_replace("\t""\033[30;1m\\t\033[0m"$content);
  190.             }
  191.  
  192.             if (in_array(' '$exclude=== false{
  193.                 $content str_replace(' '"\033[30;1m·\033[0m"$content);
  194.             }
  195.         }//end if
  196.  
  197.         return $content;
  198.  
  199.     }//end prepareForOutput()
  200.  
  201.  
  202.     /**
  203.      * Returns true if the specified string is in the camel caps format.
  204.      *
  205.      * @param string  $string      The string the verify.
  206.      * @param boolean $classFormat If true, check to see if the string is in the
  207.      *                              class format. Class format strings must start
  208.      *                              with a capital letter and contain no
  209.      *                              underscores.
  210.      * @param boolean $public      If true, the first character in the string
  211.      *                              must be an a-z character. If false, the
  212.      *                              character must be an underscore. This
  213.      *                              argument is only applicable if $classFormat
  214.      *                              is false.
  215.      * @param boolean $strict      If true, the string must not have two capital
  216.      *                              letters next to each other. If false, a
  217.      *                              relaxed camel caps policy is used to allow
  218.      *                              for acronyms.
  219.      *
  220.      * @return boolean 
  221.      */
  222.     public static function isCamelCaps(
  223.         $string,
  224.         $classFormat=false,
  225.         $public=true,
  226.         $strict=true
  227.     {
  228.         // Check the first character first.
  229.         if ($classFormat === false{
  230.             $legalFirstChar '';
  231.             if ($public === false{
  232.                 $legalFirstChar '[_]';
  233.             }
  234.  
  235.             if ($strict === false{
  236.                 // Can either start with a lowercase letter, or multiple uppercase
  237.                 // in a row, representing an acronym.
  238.                 $legalFirstChar .= '([A-Z]{2,}|[a-z])';
  239.             else {
  240.                 $legalFirstChar .= '[a-z]';
  241.             }
  242.         else {
  243.             $legalFirstChar '[A-Z]';
  244.         }
  245.  
  246.         if (preg_match("/^$legalFirstChar/"$string=== 0{
  247.             return false;
  248.         }
  249.  
  250.         // Check that the name only contains legal characters.
  251.         $legalChars 'a-zA-Z0-9';
  252.         if (preg_match("|[^$legalChars]|"substr($string1)) > 0{
  253.             return false;
  254.         }
  255.  
  256.         if ($strict === true{
  257.             // Check that there are not two capital letters next to each other.
  258.             $length          strlen($string);
  259.             $lastCharWasCaps $classFormat;
  260.  
  261.             for ($i = 1; $i $length$i++{
  262.                 $ascii ord($string{$i});
  263.                 if ($ascii >= 48 && $ascii <= 57{
  264.                     // The character is a number, so it cant be a capital.
  265.                     $isCaps = false;
  266.                 else {
  267.                     if (strtoupper($string{$i}=== $string{$i}{
  268.                         $isCaps = true;
  269.                     else {
  270.                         $isCaps = false;
  271.                     }
  272.                 }
  273.  
  274.                 if ($isCaps === true && $lastCharWasCaps === true{
  275.                     return false;
  276.                 }
  277.  
  278.                 $lastCharWasCaps $isCaps;
  279.             }
  280.         }//end if
  281.  
  282.         return true;
  283.  
  284.     }//end isCamelCaps()
  285.  
  286.  
  287.     /**
  288.      * Returns true if the specified string is in the underscore caps format.
  289.      *
  290.      * @param string $string The string to verify.
  291.      *
  292.      * @return boolean 
  293.      */
  294.     public static function isUnderscoreName($string)
  295.     {
  296.         // If there are space in the name, it can't be valid.
  297.         if (strpos($string' '!== false{
  298.             return false;
  299.         }
  300.  
  301.         $validName = true;
  302.         $nameBits  explode('_'$string);
  303.  
  304.         if (preg_match('|^[A-Z]|'$string=== 0{
  305.             // Name does not begin with a capital letter.
  306.             $validName = false;
  307.         else {
  308.             foreach ($nameBits as $bit{
  309.                 if ($bit === ''{
  310.                     continue;
  311.                 }
  312.  
  313.                 if ($bit{0!== strtoupper($bit{0})) {
  314.                     $validName = false;
  315.                     break;
  316.                 }
  317.             }
  318.         }
  319.  
  320.         return $validName;
  321.  
  322.     }//end isUnderscoreName()
  323.  
  324.  
  325.     /**
  326.      * Returns a valid variable type for param/var tag.
  327.      *
  328.      * If type is not one of the standard type, it must be a custom type.
  329.      * Returns the correct type name suggestion if type name is invalid.
  330.      *
  331.      * @param string $varType The variable type to process.
  332.      *
  333.      * @return string 
  334.      */
  335.     public static function suggestType($varType)
  336.     {
  337.         if ($varType === ''{
  338.             return '';
  339.         }
  340.  
  341.         if (in_array($varTypeself::$allowedTypes=== true{
  342.             return $varType;
  343.         else {
  344.             $lowerVarType strtolower($varType);
  345.             switch ($lowerVarType{
  346.             case 'bool':
  347.             case 'boolean':
  348.                 return 'boolean';
  349.             case 'double':
  350.             case 'real':
  351.             case 'float':
  352.                 return 'float';
  353.             case 'int':
  354.             case 'integer':
  355.                 return 'integer';
  356.             case 'array()':
  357.             case 'array':
  358.                 return 'array';
  359.             }//end switch
  360.  
  361.             if (strpos($lowerVarType'array('!== false{
  362.                 // Valid array declaration:
  363.                 // array, array(type), array(type1 => type2).
  364.                 $matches = array();
  365.                 $pattern '/^array\(\s*([^\s^=^>]*)(\s*=>\s*(.*))?\s*\)/i';
  366.                 if (preg_match($pattern$varType$matches!== 0{
  367.                     $type1 '';
  368.                     if (isset($matches[1]=== true{
  369.                         $type1 $matches[1];
  370.                     }
  371.  
  372.                     $type2 '';
  373.                     if (isset($matches[3]=== true{
  374.                         $type2 $matches[3];
  375.                     }
  376.  
  377.                     $type1 = self::suggestType($type1);
  378.                     $type2 = self::suggestType($type2);
  379.                     if ($type2 !== ''{
  380.                         $type2 ' => '.$type2;
  381.                     }
  382.  
  383.                     return "array($type1$type2)";
  384.                 else {
  385.                     return 'array';
  386.                 }//end if
  387.             else if (in_array($lowerVarTypeself::$allowedTypes=== true{
  388.                 // A valid type, but not lower cased.
  389.                 return $lowerVarType;
  390.             else {
  391.                 // Must be a custom type name.
  392.                 return $varType;
  393.             }//end if
  394.         }//end if
  395.  
  396.     }//end suggestType()
  397.  
  398.  
  399.     /**
  400.      * Given a sniff class name, returns the code for the sniff.
  401.      *
  402.      * @param string $sniffClass The fully qualified sniff class name.
  403.      *
  404.      * @return string 
  405.      */
  406.     public static function getSniffCode($sniffClass)
  407.     {
  408.         $parts explode('\\'$sniffClass);
  409.         $sniff array_pop($parts);
  410.  
  411.         if (substr($sniff-5=== 'Sniff'{
  412.             // Sniff class name.
  413.             $sniff substr($sniff0-5);
  414.         else {
  415.             // Unit test class name.
  416.             $sniff substr($sniff0-8);
  417.         }
  418.  
  419.         $category array_pop($parts);
  420.         $sniffDir array_pop($parts);
  421.         $standard array_pop($parts);
  422.         $code     $standard.'.'.$category.'.'.$sniff;
  423.         return $code;
  424.  
  425.     }//end getSniffCode()
  426.  
  427.  
  428.     /**
  429.      * Removes project-specific information from a sniff class name.
  430.      *
  431.      * @param string $sniffClass The fully qualified sniff class name.
  432.      *
  433.      * @return string 
  434.      */
  435.     public static function cleanSniffClass($sniffClass)
  436.     {
  437.         $newName strtolower($sniffClass);
  438.  
  439.         $sniffPos strrpos($newName'\sniffs\\');
  440.         if ($sniffPos === false{
  441.             // Nothing we can do as it isn't in a known format.
  442.             return $newName;
  443.         }
  444.  
  445.         $end   (strlen($newName$sniffPos + 1);
  446.         $start strrpos($newName'\\'($end * -1));
  447.  
  448.         if ($start === false{
  449.             // Nothing needs to be cleaned.
  450.             return $newName;
  451.         }
  452.  
  453.         $newName substr($newName($start + 1));
  454.         return $newName;
  455.  
  456.     }//end cleanSniffClass()
  457.  
  458.  
  459. }//end class

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