diff --git a/classes/controllers/FrmXMLController.php b/classes/controllers/FrmXMLController.php index 169b37385b..230582ed8a 100644 --- a/classes/controllers/FrmXMLController.php +++ b/classes/controllers/FrmXMLController.php @@ -476,7 +476,7 @@ public static function generate_xml( $type, $args = array() ) { // phpcs:ignore $args = wp_parse_args( $args, $defaults ); // Make sure ids are numeric. - if ( is_array( $args['ids'] ) && ! empty( $args['ids'] ) ) { + if ( is_array( $args['ids'] ) && $args['ids'] ) { $args['ids'] = array_filter( $args['ids'], 'is_numeric' ); } diff --git a/classes/helpers/FrmFieldsHelper.php b/classes/helpers/FrmFieldsHelper.php index d3dcb3d9a8..6f25ac2cbe 100644 --- a/classes/helpers/FrmFieldsHelper.php +++ b/classes/helpers/FrmFieldsHelper.php @@ -1597,7 +1597,7 @@ public static function get_other_val( $args ) { // phpcs:ignore SlevomatCodingSt } // For multi-select dropdowns only - if ( is_array( $field['value'] ) && ! empty( $field['value'] ) ) { + if ( is_array( $field['value'] ) && $field['value'] ) { $other_val = reset( $field['value'] ); } }//end if diff --git a/classes/helpers/FrmXMLHelper.php b/classes/helpers/FrmXMLHelper.php index d4a260d0b1..fffb659c72 100644 --- a/classes/helpers/FrmXMLHelper.php +++ b/classes/helpers/FrmXMLHelper.php @@ -2223,7 +2223,7 @@ private static function format_email_data( &$atts, $notification ) { if ( 'custom' === $notification[ $f ] ) { $atts[ $f ] = $notification[ 'cust_' . $f ]; - } elseif ( is_numeric( $atts[ $f ] ) && ! empty( $atts[ $f ] ) ) { + } elseif ( is_numeric( $atts[ $f ] ) && $atts[ $f ] ) { $atts[ $f ] = '[' . $atts[ $f ] . ']'; } } diff --git a/classes/models/FrmForm.php b/classes/models/FrmForm.php index 841e4b9c1a..d876bea3d8 100644 --- a/classes/models/FrmForm.php +++ b/classes/models/FrmForm.php @@ -840,7 +840,7 @@ public static function get_key_by_id( $id ) { * @return void */ public static function maybe_get_form( &$form ) { - if ( ! is_object( $form ) && ! is_array( $form ) && ! empty( $form ) ) { + if ( ! is_object( $form ) && ! is_array( $form ) && $form ) { $form = self::getOne( $form ); } } diff --git a/phpcs-sniffs/Formidable/Sniffs/CodeAnalysis/RedundantEmptyAfterTypeCheckSniff.php b/phpcs-sniffs/Formidable/Sniffs/CodeAnalysis/RedundantEmptyAfterTypeCheckSniff.php new file mode 100644 index 0000000000..3e220763c0 --- /dev/null +++ b/phpcs-sniffs/Formidable/Sniffs/CodeAnalysis/RedundantEmptyAfterTypeCheckSniff.php @@ -0,0 +1,229 @@ +getTokens(); + + // Check if this is a recognized check function or isset. + $funcName = $tokens[ $stackPtr ]['content']; + + if ( $tokens[ $stackPtr ]['code'] === T_ISSET ) { + $funcName = 'isset'; + } elseif ( ! in_array( $funcName, $this->checkFunctions, true ) ) { + return; + } + + // Find the opening parenthesis. + $checkOpenParen = $phpcsFile->findNext( T_WHITESPACE, $stackPtr + 1, null, true ); + + if ( false === $checkOpenParen || $tokens[ $checkOpenParen ]['code'] !== T_OPEN_PARENTHESIS ) { + return; + } + + if ( ! isset( $tokens[ $checkOpenParen ]['parenthesis_closer'] ) ) { + return; + } + + $checkCloseParen = $tokens[ $checkOpenParen ]['parenthesis_closer']; + + // Get the argument to the check function. + $checkArg = $this->getArgumentString( $phpcsFile, $checkOpenParen + 1, $checkCloseParen ); + + if ( empty( $checkArg ) ) { + return; + } + + // Look for && after the check. + $nextToken = $phpcsFile->findNext( T_WHITESPACE, $checkCloseParen + 1, null, true ); + + // Check if we're inside a larger parenthesized expression. + if ( false !== $nextToken && $tokens[ $nextToken ]['code'] === T_CLOSE_PARENTHESIS ) { + $nextToken = $phpcsFile->findNext( T_WHITESPACE, $nextToken + 1, null, true ); + } + + if ( false === $nextToken || $tokens[ $nextToken ]['code'] !== T_BOOLEAN_AND ) { + return; + } + + // Look for ! empty( ... ) after &&. + $afterAnd = $phpcsFile->findNext( T_WHITESPACE, $nextToken + 1, null, true ); + + if ( false === $afterAnd ) { + return; + } + + // Check for negation. + if ( $tokens[ $afterAnd ]['code'] !== T_BOOLEAN_NOT ) { + return; + } + + $emptyToken = $phpcsFile->findNext( T_WHITESPACE, $afterAnd + 1, null, true ); + + if ( false === $emptyToken || $tokens[ $emptyToken ]['code'] !== T_EMPTY ) { + return; + } + + // Find the opening parenthesis of empty. + $emptyOpenParen = $phpcsFile->findNext( T_WHITESPACE, $emptyToken + 1, null, true ); + + if ( false === $emptyOpenParen || $tokens[ $emptyOpenParen ]['code'] !== T_OPEN_PARENTHESIS ) { + return; + } + + if ( ! isset( $tokens[ $emptyOpenParen ]['parenthesis_closer'] ) ) { + return; + } + + $emptyCloseParen = $tokens[ $emptyOpenParen ]['parenthesis_closer']; + + // Get the argument to empty. + $emptyArg = $this->getArgumentString( $phpcsFile, $emptyOpenParen + 1, $emptyCloseParen ); + + if ( empty( $emptyArg ) ) { + return; + } + + // Check if the arguments match. + if ( $checkArg !== $emptyArg ) { + return; + } + + $fix = $phpcsFile->addFixableError( + 'Redundant empty() after %s(). Use "%s( %s ) && %s" instead of "%s( %s ) && ! empty( %s )".', + $emptyToken, + 'RedundantEmpty', + array( $funcName, $funcName, $checkArg, $checkArg, $funcName, $checkArg, $checkArg ) + ); + + if ( true === $fix ) { + $phpcsFile->fixer->beginChangeset(); + + // Remove "! empty( " and keep just the argument content. + // Remove the "! " (negation and space after it). + $phpcsFile->fixer->replaceToken( $afterAnd, '' ); + + // Remove whitespace between ! and empty. + for ( $i = $afterAnd + 1; $i < $emptyToken; $i++ ) { + $phpcsFile->fixer->replaceToken( $i, '' ); + } + + // Remove "empty". + $phpcsFile->fixer->replaceToken( $emptyToken, '' ); + + // Remove whitespace and opening paren. + for ( $i = $emptyToken + 1; $i <= $emptyOpenParen; $i++ ) { + $phpcsFile->fixer->replaceToken( $i, '' ); + } + + // Remove the first whitespace inside the parenthesis (after open paren). + $firstArgToken = $phpcsFile->findNext( T_WHITESPACE, $emptyOpenParen + 1, $emptyCloseParen, true ); + + if ( false !== $firstArgToken ) { + for ( $i = $emptyOpenParen + 1; $i < $firstArgToken; $i++ ) { + $phpcsFile->fixer->replaceToken( $i, '' ); + } + } + + // Remove whitespace before closing paren and the closing paren itself. + $lastArgToken = $phpcsFile->findPrevious( T_WHITESPACE, $emptyCloseParen - 1, $emptyOpenParen, true ); + + if ( false !== $lastArgToken ) { + for ( $i = $lastArgToken + 1; $i <= $emptyCloseParen; $i++ ) { + $phpcsFile->fixer->replaceToken( $i, '' ); + } + } + + $phpcsFile->fixer->endChangeset(); + } + } + + /** + * Get the argument string from between parentheses. + * + * @param File $phpcsFile The file being scanned. + * @param int $start Start position (after open paren). + * @param int $end End position (close paren). + * + * @return string + */ + private function getArgumentString( File $phpcsFile, $start, $end ) { + $tokens = $phpcsFile->getTokens(); + $arg = ''; + + for ( $i = $start; $i < $end; $i++ ) { + if ( $tokens[ $i ]['code'] === T_WHITESPACE ) { + continue; + } + + $arg .= $tokens[ $i ]['content']; + } + + return $arg; + } +} diff --git a/phpcs-sniffs/Formidable/ruleset.xml b/phpcs-sniffs/Formidable/ruleset.xml index 3a7a1fb801..137f34aec4 100644 --- a/phpcs-sniffs/Formidable/ruleset.xml +++ b/phpcs-sniffs/Formidable/ruleset.xml @@ -39,6 +39,7 @@ + diff --git a/tests/phpunit/base/FrmUnitTest.php b/tests/phpunit/base/FrmUnitTest.php index 77e4e4e474..9a83e61989 100644 --- a/tests/phpunit/base/FrmUnitTest.php +++ b/tests/phpunit/base/FrmUnitTest.php @@ -502,7 +502,7 @@ public static function generate_xml( $type, $xml_args ) { // phpcs:ignore Slevom $args = wp_parse_args( $xml_args, $defaults ); // Make sure ids are numeric. - if ( is_array( $args['ids'] ) && ! empty( $args['ids'] ) ) { + if ( is_array( $args['ids'] ) && $args['ids'] ) { $args['ids'] = array_filter( $args['ids'], 'is_numeric' ); }