diff --git a/classes/helpers/FrmAppHelper.php b/classes/helpers/FrmAppHelper.php index 14e53683cd..aee17b82a1 100644 --- a/classes/helpers/FrmAppHelper.php +++ b/classes/helpers/FrmAppHelper.php @@ -3044,7 +3044,7 @@ private static function fill_form_defaults( $post_values, array &$values ) { foreach ( array( 'before', 'after', 'submit' ) as $h ) { if ( ! isset( $values[ $h . '_html' ] ) ) { - $values[ $h . '_html' ] = ( $post_values['options'][ $h . '_html' ] ?? FrmFormsHelper::get_default_html( $h ) ); + $values[ $h . '_html' ] = $post_values['options'][ $h . '_html' ] ?? FrmFormsHelper::get_default_html( $h ); } unset( $h ); } diff --git a/classes/helpers/FrmFormsHelper.php b/classes/helpers/FrmFormsHelper.php index 1d6da52594..d889ea1260 100644 --- a/classes/helpers/FrmFormsHelper.php +++ b/classes/helpers/FrmFormsHelper.php @@ -1367,7 +1367,7 @@ public static function format_link_html( $link_details, $length = 'label' ) { $link .= ' onclick="return confirm(\'' . esc_attr( $link_details['confirm'] ) . '\')"'; } - $label = ( $link_details[ $length ] ?? $link_details['label'] ); + $label = $link_details[ $length ] ?? $link_details['label']; if ( $length === 'icon' && isset( $link_details[ $length ] ) ) { $label = ''; diff --git a/classes/helpers/FrmStylesCardHelper.php b/classes/helpers/FrmStylesCardHelper.php index 18bd650150..f769ed9a4a 100644 --- a/classes/helpers/FrmStylesCardHelper.php +++ b/classes/helpers/FrmStylesCardHelper.php @@ -271,7 +271,7 @@ public static function get_style_param_for_card( $style ) { if ( empty( $style->post_content['fieldset_bg_color'] ) ) { $background_color = '#fff'; } else { - $background_color = ( str_starts_with( $style->post_content['fieldset_bg_color'], 'rgb' ) ? $style->post_content['fieldset_bg_color'] : '#' . $style->post_content['fieldset_bg_color'] ); + $background_color = str_starts_with( $style->post_content['fieldset_bg_color'], 'rgb' ) ? $style->post_content['fieldset_bg_color'] : '#' . $style->post_content['fieldset_bg_color']; } $styles[] = '--preview-background-color: ' . $background_color; diff --git a/classes/models/FrmEmail.php b/classes/models/FrmEmail.php index 045b48d9a3..89f0bb8db0 100644 --- a/classes/models/FrmEmail.php +++ b/classes/models/FrmEmail.php @@ -663,7 +663,7 @@ private function prepare_email_setting( $value, $user_id_args ) { * @return array|string $emails */ private function explode_emails( $emails ) { - $emails = ( ! empty( $emails ) ? preg_split( '/(,|;)/', $emails ) : '' ); + $emails = ! empty( $emails ) ? preg_split( '/(,|;)/', $emails ) : ''; return is_array( $emails ) ? array_map( 'trim', $emails ) : trim( $emails ); } diff --git a/classes/models/FrmFormAction.php b/classes/models/FrmFormAction.php index b4dfea5c2a..0c4bc8f70f 100644 --- a/classes/models/FrmFormAction.php +++ b/classes/models/FrmFormAction.php @@ -257,7 +257,7 @@ protected function get_group( $action_options ) { */ public function get_field_name( $field_name, $post_field = 'post_content' ) { $name = $this->option_name . '[' . $this->number . ']'; - $name .= ( empty( $post_field ) ? '' : '[' . $post_field . ']' ); + $name .= empty( $post_field ) ? '' : '[' . $post_field . ']'; return $name . ( '[' . $field_name . ']' ); } diff --git a/classes/models/fields/FrmFieldUserID.php b/classes/models/fields/FrmFieldUserID.php index fd92dede94..594726bc9d 100644 --- a/classes/models/fields/FrmFieldUserID.php +++ b/classes/models/fields/FrmFieldUserID.php @@ -64,9 +64,9 @@ public function prepare_field_html( $args ) { */ protected function get_field_value( $args ) { $user_ID = get_current_user_id(); - $user_ID = ( $user_ID ? $user_ID : '' ); + $user_ID = $user_ID ? $user_ID : ''; $posted_value = ( FrmAppHelper::is_admin() && $_POST && isset( $_POST['item_meta'][ $this->field['id'] ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing - $action = ( $args['action'] ?? $args['form_action'] ?? '' ); + $action = $args['action'] ?? $args['form_action'] ?? ''; $updating = $action === 'update'; return is_numeric( $this->field['value'] ) || $posted_value || $updating ? $this->field['value'] : $user_ID; } diff --git a/phpcs-sniffs/Formidable/Sniffs/CodeAnalysis/RedundantParenthesesSniff.php b/phpcs-sniffs/Formidable/Sniffs/CodeAnalysis/RedundantParenthesesSniff.php new file mode 100644 index 0000000000..8b22bf1cfc --- /dev/null +++ b/phpcs-sniffs/Formidable/Sniffs/CodeAnalysis/RedundantParenthesesSniff.php @@ -0,0 +1,203 @@ +getTokens(); + + // Must have a closing parenthesis. + if ( ! isset( $tokens[ $stackPtr ]['parenthesis_closer'] ) ) { + return; + } + + $closeParen = $tokens[ $stackPtr ]['parenthesis_closer']; + + // Check what's before the opening parenthesis. + $prevToken = $phpcsFile->findPrevious( T_WHITESPACE, $stackPtr - 1, null, true ); + + if ( false === $prevToken ) { + return; + } + + // We only care about parentheses after an assignment operator or array arrow. + $assignmentTokens = array( + T_EQUAL, + T_DOUBLE_ARROW, + T_COALESCE_EQUAL, + T_PLUS_EQUAL, + T_MINUS_EQUAL, + T_CONCAT_EQUAL, + ); + + if ( ! in_array( $tokens[ $prevToken ]['code'], $assignmentTokens, true ) ) { + return; + } + + // Check what's after the closing parenthesis. + $afterClose = $phpcsFile->findNext( T_WHITESPACE, $closeParen + 1, null, true ); + + if ( false === $afterClose ) { + return; + } + + // The expression should end with a semicolon or comma (for array elements). + if ( $tokens[ $afterClose ]['code'] !== T_SEMICOLON && $tokens[ $afterClose ]['code'] !== T_COMMA && $tokens[ $afterClose ]['code'] !== T_CLOSE_PARENTHESIS ) { + return; + } + + // Check if the content inside is a simple expression (no complex operators that would need grouping). + if ( ! $this->isSimpleExpression( $phpcsFile, $stackPtr, $closeParen ) ) { + return; + } + + $fix = $phpcsFile->addFixableError( + 'Redundant parentheses around simple expression', + $stackPtr, + 'Found' + ); + + if ( true === $fix ) { + $phpcsFile->fixer->beginChangeset(); + + // Remove opening parenthesis. + $phpcsFile->fixer->replaceToken( $stackPtr, '' ); + + // Remove whitespace after opening parenthesis. + $next = $stackPtr + 1; + + while ( $next < $closeParen && $tokens[ $next ]['code'] === T_WHITESPACE ) { + $phpcsFile->fixer->replaceToken( $next, '' ); + ++$next; + } + + // Remove whitespace before closing parenthesis. + $prev = $closeParen - 1; + + while ( $prev > $stackPtr && $tokens[ $prev ]['code'] === T_WHITESPACE ) { + $phpcsFile->fixer->replaceToken( $prev, '' ); + --$prev; + } + + // Remove closing parenthesis. + $phpcsFile->fixer->replaceToken( $closeParen, '' ); + + $phpcsFile->fixer->endChangeset(); + } + } + + /** + * Check if the expression inside parentheses is simple enough that parentheses are redundant. + * + * A simple expression is one that: + * - Contains only a null coalescing operator (??) + * - Contains only a ternary operator + * - Is a single value/variable/function call + * + * @param File $phpcsFile The file being scanned. + * @param int $openParen The position of the opening parenthesis. + * @param int $closeParen The position of the closing parenthesis. + * + * @return bool True if the expression is simple, false otherwise. + */ + private function isSimpleExpression( File $phpcsFile, $openParen, $closeParen ) { + $tokens = $phpcsFile->getTokens(); + + // Count operators that would make this a complex expression. + $hasCoalesce = false; + $hasTernary = false; + $hasLogicalOp = false; + $hasComparisonOp = false; + $hasArithmeticOp = false; + $nestedParenDepth = 0; + + for ( $i = $openParen + 1; $i < $closeParen; $i++ ) { + $code = $tokens[ $i ]['code']; + + // Track nested parentheses - we only care about the top level. + if ( $code === T_OPEN_PARENTHESIS ) { + ++$nestedParenDepth; + continue; + } + + if ( $code === T_CLOSE_PARENTHESIS ) { + --$nestedParenDepth; + continue; + } + + // Skip tokens inside nested parentheses. + if ( $nestedParenDepth > 0 ) { + continue; + } + + // Check for various operators. + if ( $code === T_COALESCE ) { + $hasCoalesce = true; + } elseif ( $code === T_INLINE_THEN || $code === T_INLINE_ELSE ) { + $hasTernary = true; + } elseif ( in_array( $code, array( T_BOOLEAN_AND, T_BOOLEAN_OR, T_LOGICAL_AND, T_LOGICAL_OR, T_LOGICAL_XOR ), true ) ) { + $hasLogicalOp = true; + } elseif ( in_array( $code, array( T_IS_EQUAL, T_IS_NOT_EQUAL, T_IS_IDENTICAL, T_IS_NOT_IDENTICAL, T_LESS_THAN, T_GREATER_THAN, T_IS_SMALLER_OR_EQUAL, T_IS_GREATER_OR_EQUAL, T_SPACESHIP ), true ) ) { + $hasComparisonOp = true; + } elseif ( in_array( $code, array( T_PLUS, T_MINUS, T_MULTIPLY, T_DIVIDE, T_MODULUS ), true ) ) { + $hasArithmeticOp = true; + } + } + + // If there are logical or comparison operators combined with other operators, it's complex. + if ( $hasLogicalOp || $hasComparisonOp ) { + return false; + } + + // If there are arithmetic operators, it might need parentheses for precedence. + if ( $hasArithmeticOp ) { + return false; + } + + // A simple null coalesce or ternary without other operators is fine. + if ( $hasCoalesce || $hasTernary ) { + return true; + } + + // If there are no operators at all, it's a simple value - parentheses are redundant. + return true; + } +} diff --git a/phpcs.xml b/phpcs.xml index ded8c3252c..f63296a2b8 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -283,4 +283,5 @@ +