Skip to content

gpcc-copy-to-conditionally-hidden-fields.php: Fixed an issue with copying value with multi input field triggers. #1069

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 8, 2025

Conversation

saifsultanc
Copy link
Contributor

Context

⛑️ Ticket(s): https://secure.helpscout.net/conversation/2893866689/81562

Summary

The snippet above to Copy Values for Conditionally Hidden Fields doesn't support conditional copy cat.

Demo of the issue (Samuel):
https://www.loom.com/share/a49b8943c29e4955a807135bd7df24f9

Demo of the fix:
https://www.loom.com/share/43be9c8dbb8740448fd3102b8fb995a5

…opying value with multi input field triggers.
Copy link

coderabbitai bot commented Apr 5, 2025

Walkthrough

The update enhances the Gravity Forms Copy Cat functionality by adding logic to handle conditional fields. For each target field, the code retrieves an associated condition field from the submission entry. If the condition field represents a multi-input field (detected via a dot in its identifier), the identifier is split to access the specific index. The code then verifies whether the retrieved condition value matches the expected value from the field’s choices. If the condition is not met, the process skips the value copying and continues to the next target. No public APIs were altered in this change.

Changes

File(s) Change Summary
gp-copy-cat/gpcc-copy-to-conditionally-hidden-fields.php Enhanced logic to retrieve and check condition field values. For multi-input fields, splits the identifier to access the correct index and verifies that the condition is met before copying values; otherwise, it skips copying.

Sequence Diagram(s)

sequenceDiagram
    participant GPCC as "Copy Cat Module"
    participant Entry as "Submission Entry"
    
    GPCC ->> Entry: Retrieve associated condition field value
    Note right of GPCC: Check if field is multi-input (identifier contains ".")
    GPCC ->> Entry: Parse identifier to access specific input (if applicable)
    GPCC ->> Entry: Compare retrieved value with expected condition
    alt Condition met
        GPCC ->> GPCC: Copy source field value to target field
    else Condition not met
        GPCC ->> GPCC: Skip copying and continue to the next target
    end
Loading

Suggested reviewers

  • veryspry
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

github-actions bot commented Apr 5, 2025

Warnings
⚠️ When ready, don't forget to request reviews on this pull request from your fellow wizards.

Generated by 🚫 dangerJS against e89d0ba

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
gp-copy-cat/gpcc-copy-to-conditionally-hidden-fields.php (3)

32-35: Missing error handling for non-existent fields.

The code retrieves source and condition fields without verifying their existence first. If either $target['source'] or $target['condition'] refers to a non-existent field ID, this could lead to PHP errors.

Consider adding validation before attempting to access these fields:

+			if ( ! isset( $target['source'] ) || ! isset( $target['condition'] ) ) {
+				continue;
+			}
+
 			$source_field    = GFAPI::get_field( $form, $target['source'] );
 			$source_values   = $source_field->get_value_submission( array() );
 			$condition_field = GFAPI::get_field( $form, $target['condition'] );
+			
+			if ( empty( $source_field ) || empty( $condition_field ) ) {
+				continue;
+			}
+			
 			$condition_value = $condition_field->get_value_submission( $entry );

37-48: Improve multi-input field condition handling with additional validations.

The code correctly identifies multi-input fields by checking for dots in the identifier, but could benefit from additional validations to prevent potential issues.

Consider these improvements:

 			// for multi-input fields, we need to check the index
 			// to see if the condition is met.
 			if ( strpos( $target['condition'], '.' ) !== false ) {
 				list( $base, $index ) = explode( '.', $target['condition'] );
+				
+				// Ensure index is numeric and that choices exists
+				if ( ! is_numeric( $index ) || ! isset( $condition_field['choices'] ) || ! is_array( $condition_field['choices'] ) ) {
+					continue;
+				}
+				
 				if ( isset( $condition_field['choices'][ (int) $index ] ) ) {
 					if ( $condition_field['choices'][ (int) $index ]['value'] !== $condition_value ) {
 						continue;
 					}
 				} else {
 					continue;
 				}
 			}

32-48: Add comprehensive documentation for the conditional copy logic.

While the code includes basic comments, adding more detailed documentation would improve maintainability, especially since this is handling complex form field interactions.

Consider adding more detailed documentation before the conditional logic:

+			/**
+			 * Handle conditional copying based on field conditions
+			 * 
+			 * For multi-input fields (like checkboxes, radio buttons),
+			 * we need to check if the specific choice is selected 
+			 * before copying the value to the target field.
+			 *
+			 * @param array $target       The target field configuration.
+			 * @param array $entry        The form entry data.
+			 * @param array $source_field The source field object.
+			 */
 			$source_field    = GFAPI::get_field( $form, $target['source'] );
 			$source_values   = $source_field->get_value_submission( array() );
 			$condition_field = GFAPI::get_field( $form, $target['condition'] );
 			$condition_value = $condition_field->get_value_submission( $entry );
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 116f997 and e89d0ba.

📒 Files selected for processing (1)
  • gp-copy-cat/gpcc-copy-to-conditionally-hidden-fields.php (1 hunks)
🔇 Additional comments (2)
gp-copy-cat/gpcc-copy-to-conditionally-hidden-fields.php (2)

50-57: LGTM! The value copying logic is robust.

The implementation properly handles both array values (multi-input fields) and scalar values, maintaining the input structure when copying from source to target fields.


39-44:

❓ Verification inconclusive

Logic for condition comparison might be incorrect.

The current implementation compares $condition_field['choices'][(int)$index]['value'] with $condition_value, but based on how Gravity Forms stores multi-input field values in entries, this comparison may not work correctly in all scenarios.

Consider verifying if the comparison logic works for all expected scenarios. For radiobutton and checkbox inputs, the condition value might need to be retrieved differently.


🏁 Script executed:

#!/bin/bash
# Search for any similar condition handling in the codebase to understand best practices
rg "condition.*field.*choices.*value" --type php -g "!vendor/*" -A 5 -B 5

Length of output: 1132


Attention: Verify Multi-Input Condition Comparison Logic

The code currently compares

$condition_field['choices'][(int) $index]['value']

with

$condition_value

in gp-copy-cat/gpcc-copy-to-conditionally-hidden-fields.php (lines 39–44). Given that Gravity Forms may store multi-input field values differently—especially for radiobutton and checkbox inputs—it’s important to double-check that this comparison correctly handles all expected scenarios.

  • Action Required:
    • Please verify that retrieving the condition value in this way aligns with Gravity Forms’ storage for both radiobutton and checkbox inputs.
    • Consider reviewing or testing against sample entries to ensure that the type cast and direct value comparison don’t overlook any edge cases.

Comment on lines +39 to +48
if ( strpos( $target['condition'], '.' ) !== false ) {
list( $base, $index ) = explode( '.', $target['condition'] );
if ( isset( $condition_field['choices'][ (int) $index ] ) ) {
if ( $condition_field['choices'][ (int) $index ]['value'] !== $condition_value ) {
continue;
}
} else {
continue;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add support for non-choice conditions.

The current implementation only handles conditions for fields with choices. Consider expanding support to other field types that don't use the 'choices' property.

Add support for other field types by checking the field type:

 			if ( strpos( $target['condition'], '.' ) !== false ) {
 				list( $base, $index ) = explode( '.', $target['condition'] );
-				if ( isset( $condition_field['choices'][ (int) $index ] ) ) {
-					if ( $condition_field['choices'][ (int) $index ]['value'] !== $condition_value ) {
-						continue;
-					}
-				} else {
-					continue;
-				}
+				
+				// Handle different field types differently
+				if ( isset( $condition_field['type'] ) ) {
+					switch ( $condition_field['type'] ) {
+						case 'checkbox':
+						case 'radio':
+						case 'select':
+							if ( isset( $condition_field['choices'][ (int) $index ] ) ) {
+								if ( $condition_field['choices'][ (int) $index ]['value'] !== $condition_value ) {
+									continue;
+								}
+							} else {
+								continue;
+							}
+							break;
+						
+						default:
+							// For other field types, use a different comparison method
+							if ( $condition_value != $target['expected_value'] ) {
+								continue;
+							}
+							break;
+					}
+				} else {
+					continue;
+				}
 			}

Note: This implementation assumes there's an 'expected_value' property in the target configuration for non-choice field types. You'll need to adjust this based on your specific needs.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ( strpos( $target['condition'], '.' ) !== false ) {
list( $base, $index ) = explode( '.', $target['condition'] );
if ( isset( $condition_field['choices'][ (int) $index ] ) ) {
if ( $condition_field['choices'][ (int) $index ]['value'] !== $condition_value ) {
continue;
}
} else {
continue;
}
}
if ( strpos( $target['condition'], '.' ) !== false ) {
list( $base, $index ) = explode( '.', $target['condition'] );
// Handle different field types differently
if ( isset( $condition_field['type'] ) ) {
switch ( $condition_field['type'] ) {
case 'checkbox':
case 'radio':
case 'select':
if ( isset( $condition_field['choices'][ (int) $index ] ) ) {
if ( $condition_field['choices'][ (int) $index ]['value'] !== $condition_value ) {
continue;
}
} else {
continue;
}
break;
default:
// For other field types, use a different comparison method
if ( $condition_value != $target['expected_value'] ) {
continue;
}
break;
}
} else {
continue;
}
}

@saifsultanc saifsultanc merged commit cd558da into master Apr 8, 2025
3 of 4 checks passed
@saifsultanc saifsultanc deleted the saif/fix/81562-fix-snippet branch April 8, 2025 04:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants