Browse files

Added all PHP 5.0-5.4 sniffs

Signed-off-by: Wim Godden <wim@wimgodden.be>
  • Loading branch information...
1 parent 75c315c commit 4d3278d079296687ed9138ceec78c6c0172be46c @wimg committed Mar 4, 2012
View
56 Sniffs/PHP/DefaultTimezoneRequiredSniff.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * PHPCompatibility_Sniffs_PHP_DefaultTimeZoneRequiredSniff.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+/**
+ * PHPCompatibility_Sniffs_PHP_DefaultTimeZoneRequiredSniff.
+ *
+ * Discourages the use of deprecated INI directives through ini_set() or ini_get().
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class PHPCompatibility_Sniffs_PHP_DefaultTimeZoneRequiredSniff implements PHP_CodeSniffer_Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ * Maybe not ideal to do this on each open tag. But I don't feel like digging further into PHP_CodeSniffer right now
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_OPEN_TAG);
+
+ }//end register()
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ if (ini_get('date.timezone') == false) {
+ $error = 'Default timezone is required since PHP 5.4';
+ $phpcsFile->addError($error, $stackPtr);
+ }
+
+ }//end process()
+
+
+}//end class
View
293 Sniffs/PHP/DeprecatedFunctionsSniff.php
@@ -0,0 +1,293 @@
+<?php
+/**
+ * PHPCompatibility_Sniffs_PHP_DeprecatedFunctionsSniff.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+/**
+ * PHPCompatibility_Sniffs_PHP_DeprecatedFunctionsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @version 1.0.0
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class PHPCompatibility_Sniffs_PHP_DeprecatedFunctionsSniff extends Generic_Sniffs_PHP_ForbiddenFunctionsSniff
+{
+
+ /**
+ * A list of forbidden functions with their alternatives.
+ *
+ * The array lists : version number with 0 (deprecated) or 1 (forbidden) and an alternative function.
+ * If no alternative exists, it is NULL. IE, the function should just not be used.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $forbiddenFunctions = array(
+ 'call_user_method' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'call_user_func'
+ ),
+ 'call_user_method_array' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'call_user_func_array'
+ ),
+ 'define_syslog_variables' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => null
+ ),
+ 'dl' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => null
+ ),
+ 'ereg' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'preg_match'
+ ),
+ 'ereg_replace' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'preg_replace'
+ ),
+ 'eregi' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'preg_match'
+ ),
+ 'eregi_replace' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'preg_replace'
+ ),
+ 'import_request_variables' => array(
+ '5.4' => true,
+ 'alternative' => null
+ ),
+ 'mcrypt_generic_end' => array(
+ '5.4' => false,
+ 'alternative' => 'mcrypt_generic_deinit'
+ ),
+ 'mysql_db_query' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'mysql_select_db and mysql_query'
+ ),
+ 'mysql_escape_string' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'mysql_real_escape_string'
+ ),
+ 'mysql_list_dbs' => array(
+ '5.4' => false,
+ 'alternative' => null
+ ),
+ 'mysqli_bind_param' => array(
+ '5.4' => true,
+ 'alternative' => 'mysqli_stmt_bind_param'
+ ),
+ 'mysqli_bind_result' => array(
+ '5.4' => true,
+ 'alternative' => 'mysqli_stmt_bind_result'
+ ),
+ 'mysqli_client_encoding' => array(
+ '5.4' => true,
+ 'alternative' => 'mysqli_charachter_set_name'
+ ),
+ 'mysqli_fetch' => array(
+ '5.4' => true,
+ 'alternative' => 'mysqli_stmt_fetch'
+ ),
+ 'mysqli_param_count' => array(
+ '5.4' => true,
+ 'alternative' => 'mysqli_stmt_param_count'
+ ),
+ 'mysqli_get_metadata' => array(
+ '5.4' => true,
+ 'alternative' => 'mysqli_stmt_result_metadata'
+ ),
+ 'mysqli_send_long_data' => array(
+ '5.4' => true,
+ 'alternative' => 'mysqli_stmt_send_long_data'
+ ),
+ 'magic_quotes_runtime' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => null
+ ),
+ 'session_register' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => 'use $_SESSION'
+ ),
+ 'session_unregister' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => 'use $_SESSION'
+ ),
+ 'session_is_registered' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => 'use $_SESSION'
+ ),
+ 'set_magic_quotes_runtime' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => null
+ ),
+ 'set_socket_blocking' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'stream_set_blocking'
+ ),
+ 'split' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'preg_split'
+ ),
+ 'spliti' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => 'preg_split'
+ ),
+ 'sql_regcase' => array(
+ '5.3' => false,
+ '5.4' => false,
+ 'alternative' => null
+ ),
+ );
+
+
+ /**
+ * If true, an error will be thrown; otherwise a warning.
+ *
+ * @var bool
+ */
+ public $error = false;
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $ignore = array(
+ T_DOUBLE_COLON,
+ T_OBJECT_OPERATOR,
+ T_FUNCTION,
+ T_CONST,
+ );
+
+ $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
+ if (in_array($tokens[$prevToken]['code'], $ignore) === true) {
+ // Not a call to a PHP function.
+ return;
+ }
+
+ $function = strtolower($tokens[$stackPtr]['content']);
+ $pattern = null;
+
+ if ($this->patternMatch === true) {
+ $count = 0;
+ $pattern = preg_replace(
+ $this->forbiddenFunctionNames,
+ $this->forbiddenFunctionNames,
+ $function,
+ 1,
+ $count
+ );
+
+ if ($count === 0) {
+ return;
+ }
+
+ // Remove the pattern delimiters and modifier.
+ $pattern = substr($pattern, 1, -2);
+ } else {
+ if (in_array($function, $this->forbiddenFunctionNames) === false) {
+ return;
+ }
+ }
+
+ $this->addError($phpcsFile, $stackPtr, $function, $pattern);
+
+ }//end process()
+
+
+ /**
+ * Generates the error or wanrning for this sniff.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the forbidden function
+ * in the token array.
+ * @param string $function The name of the forbidden function.
+ * @param string $pattern The pattern used for the match.
+ *
+ * @return void
+ */
+ protected function addError($phpcsFile, $stackPtr, $function, $pattern=null)
+ {
+ $data = array($function);
+ $error = 'The use of function %s() is ';
+
+
+ if ($this->error === true) {
+ $type = 'Found';
+ $error .= 'forbidden';
+ } else {
+ $type = 'Discouraged';
+ $error .= 'discouraged';
+ }
+
+ if ($pattern === null) {
+ $pattern = $function;
+ }
+
+ $this->error = false;
+ foreach ($this->forbiddenFunctions[$pattern] as $version => $forbidden) {
+ if ($version != 'alternative') {
+ if ($forbidden === true) {
+ $this->error = true;
+ $error .= 'forbidden';
+ } else {
+ $error .= 'discouraged';
+ }
+ $error .= 'in PHP version ' . $version . ' and ';
+ }
+ }
+ $error .= substr($error, strlen($error) - 5);
+
+ if ($this->forbiddenFunctions[$pattern]['alternative'] !== null) {
+ $type .= 'WithAlternative';
+ $data[] = $this->forbiddenFunctions[$pattern]['alternative'];
+ $error .= '; use %s() instead';
+ }
+
+ if ($this->error === true) {
+ $phpcsFile->addError($error, $stackPtr, $type, $data);
+ } else {
+ $phpcsFile->addWarning($error, $stackPtr, $type, $data);
+ }
+
+ }//end addError()
+
+}//end class
View
171 Sniffs/PHP/DeprecatedIniDirectivesSniff.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * PHPCompatibility_Sniffs_PHP_DeprecatedIniDirectivesSniff.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+/**
+ * PHPCompatibility_Sniffs_PHP_DeprecatedIniDirectivesSniff.
+ *
+ * Discourages the use of deprecated INI directives through ini_set() or ini_get().
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class PHPCompatibility_Sniffs_PHP_DeprecatedIniDirectivesSniff implements PHP_CodeSniffer_Sniff
+{
+ /**
+ * A list of deprecated INI directives
+ *
+ * @var array(string)
+ */
+ protected $deprecatedIniDirectives = array(
+ 'define_syslog_variables' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'register_globals' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'register_long_arrays' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'safe_mode' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'magic_quotes_gpc' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'magic_quotes_runtime' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'magic_quotes_sybase' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'allow_call_time_pass_reference' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'highlight.bg' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'session.bug_compat_42' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'session.bug_compat_warn' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'y2k_compliance' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'zend.ze1_compatibility_mode' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'safe_mode' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'safe_mode_gid' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'safe_mode_include_dir' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'safe_mode_exec_dir' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'safe_mode_allowed_env_vars' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ 'safe_mode_protected_env_vars' => array(
+ '5.3' => false,
+ '5.4' => true
+ ),
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+
+ }//end register()
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $ignore = array(
+ T_DOUBLE_COLON,
+ T_OBJECT_OPERATOR,
+ T_FUNCTION,
+ T_CONST,
+ );
+
+ $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
+ if (in_array($tokens[$prevToken]['code'], $ignore) === true) {
+ // Not a call to a PHP function.
+ return;
+ }
+
+ $function = strtolower($tokens[$stackPtr]['content']);
+ if ($function != 'ini_get' && $function != 'ini_set') {
+ return;
+ }
+ $iniToken = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, $stackPtr, null);
+ if (in_array(str_replace("'", "", $tokens[$iniToken]['content']), array_keys($this->deprecatedIniDirectives)) === false) {
+ return;
+ }
+ $error = "INI directive " . $tokens[$iniToken]['content'] . " is";
+ foreach ($this->deprecatedIniDirectives[str_replace("'", "", $tokens[$iniToken]['content'])] as $version => $forbidden)
+ {
+ if ($forbidden === true) {
+ $error .= " forbidden";
+ } else {
+ $error .= " deprecated";
+ }
+ $error .= " in PHP " . $version . " and ";
+ }
+ $error = substr($error, 0, strlen($error) - 5) . ".";
+
+ $phpcsFile->addWarning($error, $stackPtr);
+
+ }//end process()
+
+
+}//end class
View
68 Sniffs/PHP/DeprecatedNewReferenceSniff.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * PHPCompatibility_Sniffs_PHP_DeprecatedNewReferenceSniff.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+/**
+ * PHPCompatibility_Sniffs_PHP_DeprecatedNewReferenceSniff.
+ *
+ * Discourages the use of assigning the return value of new by reference
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class PHPCompatibility_Sniffs_PHP_DeprecatedNewReferenceSniff implements PHP_CodeSniffer_Sniff
+{
+
+ /**
+ * If true, an error will be thrown; otherwise a warning.
+ *
+ * @var bool
+ */
+ protected $error = true;
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_NEW);
+
+ }//end register()
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ if ($tokens[$stackPtr - 1]['type'] == 'T_BITWISE_AND' || $tokens[$stackPtr - 2]['type'] == 'T_BITWISE_AND') {
+ $error = 'Assigning the return value of new by reference is deprecated in PHP 5.3';
+ $phpcsFile->addError($error, $stackPtr);
+ }
+
+ }//end process()
+
+
+}//end class
View
87 Sniffs/PHP/ForbiddenBreakContinueVariableArgumentsSniff.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * PHPCompatibility_Sniffs_PHP_ForbiddenBreakContinueVariableArguments.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+/**
+ * PHPCompatibility_Sniffs_PHP_ForbiddenBreakContinueVariableArguments.
+ *
+ * Discourages the use of assigning the return value of new by reference
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class PHPCompatibility_Sniffs_PHP_ForbiddenBreakContinueVariableArgumentsSniff implements PHP_CodeSniffer_Sniff
+{
+
+ /**
+ * If true, an error will be thrown; otherwise a warning.
+ *
+ * @var bool
+ */
+ protected $error = true;
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_BREAK, T_CONTINUE);
+
+ }//end register()
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $nextSemicolonToken = $phpcsFile->findNext(T_SEMICOLON, ($stackPtr), null, false);
+ for ($curToken = $stackPtr + 1; $curToken < $nextSemicolonToken; $curToken++) {
+ $gotError = false;
+ if ($tokens[$curToken]['type'] == 'T_STRING') {
+ // If the next non-whitespace token after the string
+ // is an opening parenthesis then it's a function call.
+ $openBracket = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $curToken + 1, null, true);
+ if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) {
+ continue;
+ } else {
+ $gotError = true;
+ }
+ }
+ switch ($tokens[$curToken]['type']) {
+ case 'T_VARIABLE':
+ case 'T_FUNCTION':
+ $gotError = true;
+ break;
+ }
+ if ($gotError === true) {
+ $error = 'Using a variable argument on break or continue is not forbidden since PHP 5.4';
+ $phpcsFile->addError($error, $stackPtr);
+ }
+ }
+ }//end process()
+
+
+}//end class
View
197 Sniffs/PHP/ForbiddenNamesSniff.php
@@ -0,0 +1,197 @@
+<?php
+/**
+ * PHPCompatibility_Sniffs_PHP_ForbiddenNamesSniff.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+/**
+ * PHPCompatibility_Sniffs_PHP_ForbiddenNamesSniff.
+ *
+ * Prohibits the use of reserved keywords as class, function, namespace or constant names
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class PHPCompatibility_Sniffs_PHP_ForbiddenNamesSniff implements PHP_CodeSniffer_Sniff
+{
+
+ /**
+ * A list of keywords that can not be used as function, class and namespace name or constant name
+ * Mentions since which version it's not allowed
+ *
+ * @var array(string => string)
+ */
+ protected $invalidNames = array(
+ 'abstract' => '5.0',
+ 'and' => 'all',
+ 'array' => 'all',
+ 'as' => 'all',
+ 'break' => 'all',
+ 'callable' => '5.4',
+ 'case' => 'all',
+ 'catch' => '5.0',
+ 'class' => 'all',
+ 'clone' => '5.0',
+ 'const' => 'all',
+ 'continue' => 'all',
+ 'declare' => 'all',
+ 'default' => 'all',
+ 'do' => 'all',
+ 'else' => 'all',
+ 'elseif' => 'all',
+ 'enddeclare' => 'all',
+ 'endfor' => 'all',
+ 'endforeach' => 'all',
+ 'endif' => 'all',
+ 'endswitch' => 'all',
+ 'endwhile' => 'all',
+ 'extends' => 'all',
+ 'final' => '5.0',
+ 'for' => 'all',
+ 'foreach' => 'all',
+ 'function' => 'all',
+ 'global' => 'all',
+ 'goto' => '5.3',
+ 'if' => 'all',
+ 'implements' => '5.0',
+ 'interface' => '5.0',
+ 'instanceof' => '5.0',
+ 'insteadof' => '5.4',
+ 'namespace' => '5.3',
+ 'new' => 'all',
+ 'or' => 'all',
+ 'private' => '5.0',
+ 'protected' => '5.0',
+ 'public' => '5.0',
+ 'static' => 'all',
+ 'switch' => 'all',
+ 'throw' => '5.0',
+ 'trait' => '5.4',
+ 'try' => '5.0',
+ 'use' => 'all',
+ 'var' => 'all',
+ 'while' => 'all',
+ 'xor' => 'all',
+ '__CLASS__' => 'all',
+ '__DIR__' => '5.3',
+ '__FILE__' => 'all',
+ '__FUNCTION__' => 'all',
+ '__METHOD__' => 'all',
+ '__NAMESPACE__' => '5.3'
+ );
+
+ /**
+ * If true, an error will be thrown; otherwise a warning.
+ *
+ * @var bool
+ */
+ protected $error = true;
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_CLASS, T_FUNCTION, T_NAMESPACE, T_STRING, T_CONST);
+
+ }//end register()
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $stackPtr = $phpcsFile->findNext(array(T_CLASS, T_FUNCTION, T_NAMESPACE, T_STRING), $stackPtr);
+ /**
+ * We distinguish between the class, function and namespace names or the define statements
+ */
+ if ($tokens[$stackPtr]['type'] == 'T_STRING') {
+ $this->processString($phpcsFile, $stackPtr, $tokens);
+ } else {
+ $this->processNonString($phpcsFile, $stackPtr, $tokens);
+ }
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param array $tokens The stack of tokens that make up
+ * the file.
+ *
+ * @return void
+ */
+ public function processNonString(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens)
+ {
+ if (in_array(strtolower($tokens[$stackPtr + 2]['content']), array_keys($this->invalidNames)) === false) {
+ return;
+ }
+ $error = "Function name, class name, namespace name or constant name can not be reserved keyword '" . $tokens[$stackPtr + 2]['content'] . "' (since version " . $this->invalidNames[strtolower($tokens[$stackPtr + 2]['content'])] . ")";
+ $phpcsFile->addError($error, $stackPtr);
+
+ }//end process()
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param array $tokens The stack of tokens that make up
+ * the file.
+ *
+ * @return void
+ */
+ public function processString(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens)
+ {
+ $stackPtr = $phpcsFile->findNext(T_STRING, $stackPtr, null, null, 'define');
+ if ($stackPtr === false) {
+ return;
+ }
+
+ $closingParenthesis = $phpcsFile->findNext(T_CLOSE_PARENTHESIS, $stackPtr);
+ if ($closingParenthesis === false) {
+ return;
+ }
+
+ $defineContent = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, $stackPtr, $closingParenthesis);
+ if ($defineContent === false) {
+ return;
+ }
+
+ foreach ($this->invalidNames as $key => $value) {
+ if (substr(strtolower($tokens[$defineContent]['content']), 1, strlen($tokens[$defineContent]['content']) - 2) == $key) {
+ $error = "Function name, class name, namespace name or constant name can not be reserved keyword '" . $key . "' (since version " . $value . ")";
+ $phpcsFile->addError($error, $stackPtr);
+ }
+ }
+ }//end process()
+
+
+
+}//end class
+
+?>
View
90 Sniffs/PHP/NonStaticMagicMethodsSniff.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * PHPCompatibility_Sniffs_PHP_NonStaticMagicMethodsSniff.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+/**
+ * PHPCompatibility_Sniffs_PHP_NonStaticMagicMethodsSniff.
+ *
+ * Prohibits the use of static magic methods as well as protected or private magic methods
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class PHPCompatibility_Sniffs_PHP_NonStaticMagicMethodsSniff implements PHP_CodeSniffer_Sniff
+{
+
+ /**
+ * A list of magic methods that must be public and not be static
+ *
+ * @var array(string)
+ */
+ protected $magicMethods = array(
+ '__get',
+ '__set',
+ '__isset',
+ '__unset',
+ '__call'
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_CLASS, T_INTERFACE);
+
+ }//end register()
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $functionToken = $phpcsFile->findNext(T_FUNCTION, $stackPtr);
+ if ($functionToken === false) {
+ return;
+ }
+ $nameToken = $phpcsFile->findNext(T_STRING, $functionToken);
+ if (in_array($tokens[$nameToken]['content'], $this->magicMethods) === false) {
+ return;
+ }
+ $scopeToken = $phpcsFile->findPrevious(array(T_PUBLIC, T_PROTECTED, T_PRIVATE), $nameToken, $stackPtr);
+ if ($scopeToken === false) {
+ return;
+ }
+ if ($tokens[$scopeToken]['type'] != 'T_PUBLIC') {
+ $error = "Magic methods must be public (since PHP 5.3) !";
+ $phpcsFile->addError($error, $stackPtr);
+ }
+ $staticToken = $phpcsFile->findPrevious(T_STATIC, $scopeToken, $scopeToken - 2);
+ if ($staticToken === false) {
+ return;
+ } else {
+ $error = "Magic methods can not be static (since PHP 5.3) !";
+ $phpcsFile->addError($error, $stackPtr);
+ }
+
+ }//end process()
+
+
+}//end class
View
318 Sniffs/PHP/RemovedExtensionsSniff.php
@@ -0,0 +1,318 @@
+<?php
+/**
+ * PHPCompatibility_Sniffs_PHP_RemovedExtensionsSniff.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+/**
+ * PHPCompatibility_Sniffs_PHP_RemovedExtensionsSniff.
+ *
+ * Discourages the use of removed extensions. Suggests alternative extensions if available
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class PHPCompatibility_Sniffs_PHP_RemovedExtensionsSniff implements PHP_CodeSniffer_Sniff
+{
+
+ /**
+ * A list of removed extensions with their alternative, if any
+ * Array codes : 0 = removed/unavailable, -1 = deprecated, 1 = active
+ *
+ * @var array(string|null)
+ */
+ protected $removedExtensions = array(
+ 'activescript' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'pecl/activescript'
+ ),
+ 'cpdf' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'pecl/pdflib'
+ ),
+ 'dbase' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'dbx' => array(
+ '5.0' => 1,
+ '5.1' => 0,
+ '5.2' => 0,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'pecl/dbx'
+ ),
+ 'dio' => array(
+ '5.0' => 1,
+ '5.1' => 0,
+ '5.2' => 0,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'pecl/dio'
+ ),
+ 'fam' => array(
+ '5.0' => 1,
+ '5.1' => 0,
+ '5.2' => 0,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'fbsql' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'fdf' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'pecl/fdf'
+ ),
+ 'filepro' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 0,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'hw_api' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 0,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'ingres' => array(
+ '5.0' => 1,
+ '5.1' => 0,
+ '5.2' => 0,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'pecl/ingres'
+ ),
+ 'ircg' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'mcve' => array(
+ '5.0' => 1,
+ '5.1' => 0,
+ '5.2' => 0,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'pecl/mvce'
+ ),
+ 'mhash' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'hash'
+ ),
+ 'ming' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'pecl/ming'
+ ),
+ 'mnogosearch' => array(
+ '5.0' => 1,
+ '5.1' => 0,
+ '5.2' => 0,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'msql' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'ncurses' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'pecl/ncurses'
+ ),
+ 'oracle' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'oci8 or pdo_oci'
+ ),
+ 'ovrimos' => array(
+ '5.0' => 1,
+ '5.1' => 0,
+ '5.2' => 0,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'pfpro' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'sqlite' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 1,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ 'sybase' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'sybase_ct'
+ ),
+ 'w32api' => array(
+ '5.0' => 1,
+ '5.1' => 0,
+ '5.2' => 0,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => 'pecl/ffi'
+ ),
+ 'yp' => array(
+ '5.0' => 1,
+ '5.1' => 1,
+ '5.2' => 1,
+ '5.3' => 0,
+ '5.4' => 0,
+ 'alternative' => null
+ ),
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+
+ }//end register()
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Find the next non-empty token.
+ $openBracket = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+
+ if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) {
+ // Not a function call.
+ return;
+ }
+
+ if (isset($tokens[$openBracket]['parenthesis_closer']) === false) {
+ // Not a function call.
+ return;
+ }
+
+ // Find the previous non-empty token.
+ $search = PHP_CodeSniffer_Tokens::$emptyTokens;
+ $search[] = T_BITWISE_AND;
+ $previous = $phpcsFile->findPrevious($search, ($stackPtr - 1), null, true);
+ if ($tokens[$previous]['code'] === T_FUNCTION) {
+ // It's a function definition, not a function call.
+ return;
+ }
+
+ if ($tokens[$previous]['code'] === T_NEW) {
+ // We are creating an object, not calling a function.
+ return;
+ }
+
+ if ( $tokens[$previous]['code'] === T_OBJECT_OPERATOR ) {
+ // We are calling a method of an object
+ return;
+ }
+
+ foreach ($this->removedExtensions as $extension => $versionList) {
+ if (strpos($tokens[$stackPtr]['content'], $extension) === 0) {
+ $error = "Extension '" . $extension . "' is ";
+ foreach ($versionList as $version => $status) {
+ if ($version != 'alternative') {
+ switch ($status) {
+ case -1:
+ $error .= 'deprecated since PHP ' . $version . ' and ';
+ break;
+ case 0:
+ $error .= 'removed since PHP ' . $version . ' and ';
+ break 2;
+ }
+ }
+ }
+ $error = substr($error, 0, strlen($error) - 5);
+ if (!is_null($versionList['alternative'])) {
+ $error .= ' - use ' . $versionList['alternative'] . ' instead.';
+ }
+ $phpcsFile->addError($error, $stackPtr);
+ }
+ }
+
+ }//end process()
+
+
+}//end class
View
97 Sniffs/PHP/RemovedHashAlgorithmsSniff.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * PHPCompatibility_Sniffs_PHP_RemovedHashAlgorithmsSniff.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+/**
+ * PHPCompatibility_Sniffs_PHP_RemovedHashAlgorithmsSniff.
+ *
+ * Discourages the use of assigning the return value of new by reference
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden <wim.godden@cu.be>
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class PHPCompatibility_Sniffs_PHP_RemovedHashAlgorithmsSniff implements PHP_CodeSniffer_Sniff
+{
+
+ /**
+ * If true, an error will be thrown; otherwise a warning.
+ *
+ * @var bool
+ */
+ protected $error = true;
+
+ /**
+ * List of funtions using the algorithm as parameter (always the first parameter)
+ *
+ * @var array
+ */
+ protected $algoFunctions = array(
+ 'hash_file',
+ 'hash_hmac_file',
+ 'hash_hmac',
+ 'hash_init',
+ 'hash'
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+
+ }//end register()
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ if (in_array($tokens[$stackPtr]['content'], $this->algoFunctions) === true) {
+ $openBracket = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) {
+ return;
+ }
+ $firstParam = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($openBracket + 1), null, true);
+ /**
+ * Algorithm is a T_CONSTANT_ENCAPSED_STRING, so we need to remove the quotes
+ */
+ $algo = strtolower($tokens[$firstParam]['content']);
+ $algo = substr($algo, 1, strlen($algo) - 2);
+ switch ($algo) {
+ case 'salsa10':
+ case 'salsa20':
+ $error = 'The Salsa10 and Salsa20 hash algorithms have been removed since PHP 5.4';
+ $phpcsFile->addError($error, $stackPtr);
+ break;
+ }
+
+ }
+
+
+ }//end process()
+
+
+}//end class
View
5 ruleset.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+
+<ruleset name="PHPCompatibility_CodeSniffer">
+ <description>Coding Standard that checks for PHP version compatibility.</description>
+</ruleset>

0 comments on commit 4d3278d

Please sign in to comment.