>> */ protected $targetFunctions = [ 'crypt' => [ 2 => [ 'name' => 'salt', '5.6' => false, '8.0' => true, ], ], 'gmmktime' => [ 1 => [ 'name' => 'hour', '8.0' => true, ], ], 'mb_parse_str' => [ 2 => [ 'name' => 'result', '8.0' => true, ], ], 'mktime' => [ 1 => [ 'name' => 'hour', '5.1' => false, '8.0' => true, ], ], 'openssl_seal' => [ 5 => [ 'name' => 'cipher_algo', '8.0' => true, ], ], 'openssl_open' => [ 5 => [ 'name' => 'cipher_algo', '8.0' => true, ], ], 'parse_str' => [ 2 => [ 'name' => 'result', '7.2' => false, '8.0' => true, ], ], 'pg_fetch_result' => [ 2 => [ 'name' => 'row', '8.4' => false, ], 3 => [ 'name' => 'field', '8.4' => false, ], ], 'pg_field_prtlen' => [ 2 => [ 'name' => 'row', '8.4' => false, ], 3 => [ 'name' => 'field', '8.4' => false, ], ], 'pg_field_is_null' => [ 2 => [ 'name' => 'row', '8.4' => false, ], 3 => [ 'name' => 'field', '8.4' => false, ], ], 'stream_context_set_option' => [ 3 => [ 'name' => 'option_name', '8.4' => false, ], 4 => [ 'name' => 'value', '8.4' => false, ], ], ]; /** * Bowing out early is not applicable to this sniff. * * @since 10.0.0 * * @return bool */ protected function bowOutEarly() { return false; } /** * Process the parameters of a matched function. * * @since 10.0.0 Part of the logic in this method was previously contained in the * parent sniff `process()` method (now removed). * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the stack. * @param string $functionName The token content (function name) which was matched. * @param array $parameters Array with information about the parameters. * * @return int|void Integer stack pointer to skip forward or void to continue * normal file processing. */ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters) { $functionLc = \strtolower($functionName); foreach ($this->targetFunctions[$functionLc] as $offset => $parameterDetails) { $targetParam = PassedParameters::getParameterFromStack($parameters, $offset, $parameterDetails['name']); if ($targetParam === false) { $itemInfo = [ 'name' => $functionName, 'nameLc' => $functionLc, 'offset' => $offset, ]; $this->handleFeature($phpcsFile, $stackPtr, $itemInfo); } } } /** * Process the function if no parameters were found. * * @since 10.0.0 * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the stack. * @param string $functionName The token content (function name) which was matched. * * @return int|void Integer stack pointer to skip forward or void to continue * normal file processing. */ public function processNoParameters(File $phpcsFile, $stackPtr, $functionName) { $this->processParameters($phpcsFile, $stackPtr, $functionName, []); } /** * Retrieve the relevant detail (version) information for use in an error message. * * @since 8.1.0 * @since 10.0.0 - Method renamed from `getErrorInfo()` to `getVersionInfo(). * - Second function parameter `$itemInfo` removed. * - Method visibility changed from `public` to `protected`. * * @param array $itemArray Version and other information about the item. * * @return array */ protected function getVersionInfo(array $itemArray) { $versionInfo = [ 'optionalDeprecated' => '', 'optionalRemoved' => '', 'error' => false, ]; foreach ($itemArray as $version => $required) { if (\preg_match('`^\d\.\d(\.\d{1,2})?$`', $version) !== 1) { // Not a version key. continue; } if (ScannedCode::shouldRunOnOrAbove($version) === true) { if ($required === true && $versionInfo['optionalRemoved'] === '') { $versionInfo['optionalRemoved'] = $version; $versionInfo['error'] = true; } elseif ($versionInfo['optionalDeprecated'] === '') { $versionInfo['optionalDeprecated'] = $version; } } } return $versionInfo; } /** * Handle the retrieval of relevant information and - if necessary - throwing of an * error for a matched item. * * @since 10.0.0 This was previously handled via a similar method in the `AbstractComplexVersionSniff`. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the relevant token in * the stack. * @param array $itemInfo Base information about the item. * * @return void */ protected function handleFeature(File $phpcsFile, $stackPtr, array $itemInfo) { $itemArray = $this->targetFunctions[$itemInfo['nameLc']][$itemInfo['offset']]; $versionInfo = $this->getVersionInfo($itemArray); if (empty($versionInfo['optionalDeprecated']) && empty($versionInfo['optionalRemoved'])) { return; } $this->addError($phpcsFile, $stackPtr, $itemInfo, $itemArray, $versionInfo); } /** * Generates the error or warning for this item. * * @since 8.1.0 * @since 10.0.0 - Method visibility changed from `public` to `protected`. * - Introduced $itemArray parameter. * - Renamed the last parameter from `$errorInfo` to `$versionInfo`. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the relevant token in * the stack. * @param array $itemInfo Base information about the item. * @param array $itemArray The sub-array with all the details about * this item. * @param array $versionInfo Array with detail (version) information * relevant to the item. * * @return void */ protected function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $itemArray, array $versionInfo) { $error = 'The "%s" parameter for function %s() is missing. Passing this parameter is no longer optional. The optional nature of the parameter is '; $errorCode = MessageHelper::stringToErrorCode($itemInfo['name'] . '_' . $itemArray['name'], true); $codeSuffix = ''; $data = [ $itemArray['name'], $itemInfo['name'], ]; if ($versionInfo['optionalDeprecated'] !== '') { $error .= 'deprecated since PHP %s and '; $codeSuffix = 'Soft'; $data[] = $versionInfo['optionalDeprecated']; } if ($versionInfo['optionalRemoved'] !== '') { $error .= 'removed since PHP %s and '; $codeSuffix = 'Hard'; $data[] = $versionInfo['optionalRemoved']; } // Remove the last 'and' from the message. $error = \substr($error, 0, (\strlen($error) - 5)); $errorCode .= $codeSuffix . 'Required'; MessageHelper::addMessage($phpcsFile, $error, $stackPtr, $versionInfo['error'], $errorCode, $data); } }