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 @@
+