Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions gp-media-library/gpml-acf-user-image-field.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,64 @@ public function __construct( $args ) {

}

protected function get_attachment_id_by_filename( $filename ) {
global $wpdb;

return $wpdb->get_var( $wpdb->prepare(
"SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND guid LIKE %s LIMIT 1",
'%' . $wpdb->esc_like( $filename ) . '%'
));
}
Comment on lines +36 to +43
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve the filename matching logic for better reliability.

The current approach of using LIKE '%filename%' on the GUID field may produce unreliable results since:

  1. WordPress attachment GUIDs typically contain full URLs, not just filenames
  2. The wildcard matching could match unintended attachments
  3. There's no validation of the input filename

Consider using WordPress's built-in functions or querying by post_title or _wp_attached_file meta instead.

 protected function get_attachment_id_by_filename( $filename ) {
-	global $wpdb;
-
-	return $wpdb->get_var( $wpdb->prepare(
-		"SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND guid LIKE %s LIMIT 1",
-		'%' . $wpdb->esc_like( $filename ) . '%'
-	));
+	global $wpdb;
+	
+	// First try exact match on _wp_attached_file meta
+	$attachment_id = $wpdb->get_var( $wpdb->prepare(
+		"SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value LIKE %s LIMIT 1",
+		'%' . $wpdb->esc_like( basename( $filename ) )
+	));
+	
+	if ( $attachment_id ) {
+		return $attachment_id;
+	}
+	
+	// Fallback to post_title match
+	return $wpdb->get_var( $wpdb->prepare(
+		"SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_title = %s LIMIT 1",
+		pathinfo( $filename, PATHINFO_FILENAME )
+	));
 }
📝 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
protected function get_attachment_id_by_filename( $filename ) {
global $wpdb;
return $wpdb->get_var( $wpdb->prepare(
"SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND guid LIKE %s LIMIT 1",
'%' . $wpdb->esc_like( $filename ) . '%'
));
}
protected function get_attachment_id_by_filename( $filename ) {
global $wpdb;
// First try exact match on the _wp_attached_file meta (stores the file path)
$attachment_id = $wpdb->get_var( $wpdb->prepare(
"SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value LIKE %s LIMIT 1",
'%' . $wpdb->esc_like( basename( $filename ) )
));
if ( $attachment_id ) {
return $attachment_id;
}
// Fallback to an exact post_title match (filename without extension)
return $wpdb->get_var( $wpdb->prepare(
"SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_title = %s LIMIT 1",
pathinfo( $filename, PATHINFO_FILENAME )
));
}
🤖 Prompt for AI Agents
In gp-media-library/gpml-acf-user-image-field.php around lines 36 to 43, the
current method uses a SQL LIKE query on the GUID field to find an attachment by
filename, which is unreliable because GUIDs contain full URLs and the wildcard
can match unintended results. To fix this, replace the query to search by the
'_wp_attached_file' meta key using a meta query or join with the postmeta table,
ensuring exact matching of the filename. Also, validate the input filename
before querying to avoid invalid or empty values.


function update_user_image_field( $user_id, $feed, $entry ) {
if ( $entry['form_id'] == $this->_args['form_id'] && is_callable( 'gp_media_library' ) ) {

$form = GFAPI::get_form( $entry['form_id'] );
$value = gp_media_library()->acf_get_field_value( $this->_args['format'], $entry, GFFormsModel::get_field( $form, $this->_args['field_id'] ), $this->_args['is_multi'] );
$value = gp_media_library()->acf_get_field_value(
$this->_args['format'],
$entry,
GFFormsModel::get_field( $form, $this->_args['field_id'] ),
$this->_args['is_multi']
);

if ( $value && $this->_args['is_multi'] && $this->_args['append'] ) {
$current_value = wp_list_pluck( (array) get_field( $this->_args['meta_key'], 'user_' . $user_id ), 'ID' );
$value = array_merge( $current_value, $value );
}

$raw_json = $_POST['gform_uploaded_files'] ?? '';
$field_id = $this->_args['field_id'];
$key = 'input_' . $field_id;

if ( empty( $value ) && $raw_json ) {
$uploaded_files_array = json_decode( stripslashes( $raw_json ), true );
if ( isset( $uploaded_files_array[ $key ][0]['uploaded_filename'] ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@saifsultanc does this need to work with single file upload fields as well?

If so, you'll likely need to do a check on $_FILES if it's a single file upload field. You can check the field type like so: $field->multipleFiles

Here's an example of $_FILES with a file for a single file upload field.

image

$filename = $uploaded_files_array[ $key ][0]['uploaded_filename'];
$attachment_id = $this->get_attachment_id_by_filename( $filename );
if ( $attachment_id ) {
$value = $attachment_id;
}
}
}
Comment on lines +61 to +74
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 error handling for JSON parsing and array access.

The current code assumes the JSON structure and doesn't handle parsing errors or missing array keys, which could cause PHP warnings or unexpected behavior.

 if ( empty( $value ) && $raw_json ) {
 	$uploaded_files_array = json_decode( stripslashes( $raw_json ), true );
-	if ( isset( $uploaded_files_array[ $key ][0]['uploaded_filename'] ) ) {
+	if ( json_last_error() === JSON_ERROR_NONE && 
+	     isset( $uploaded_files_array[ $key ][0]['uploaded_filename'] ) ) {
 		$filename      = $uploaded_files_array[ $key ][0]['uploaded_filename'];
 		$attachment_id = $this->get_attachment_id_by_filename( $filename );
 		if ( $attachment_id ) {
 			$value = $attachment_id;
 		}
 	}
 }
📝 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
$raw_json = $_POST['gform_uploaded_files'] ?? '';
$field_id = $this->_args['field_id'];
$key = 'input_' . $field_id;
if ( empty( $value ) && $raw_json ) {
$uploaded_files_array = json_decode( stripslashes( $raw_json ), true );
if ( isset( $uploaded_files_array[ $key ][0]['uploaded_filename'] ) ) {
$filename = $uploaded_files_array[ $key ][0]['uploaded_filename'];
$attachment_id = $this->get_attachment_id_by_filename( $filename );
if ( $attachment_id ) {
$value = $attachment_id;
}
}
}
$raw_json = $_POST['gform_uploaded_files'] ?? '';
$field_id = $this->_args['field_id'];
$key = 'input_' . $field_id;
if ( empty( $value ) && $raw_json ) {
$uploaded_files_array = json_decode( stripslashes( $raw_json ), true );
if ( json_last_error() === JSON_ERROR_NONE &&
isset( $uploaded_files_array[ $key ][0]['uploaded_filename'] ) ) {
$filename = $uploaded_files_array[ $key ][0]['uploaded_filename'];
$attachment_id = $this->get_attachment_id_by_filename( $filename );
if ( $attachment_id ) {
$value = $attachment_id;
}
}
}
🤖 Prompt for AI Agents
In gp-media-library/gpml-acf-user-image-field.php around lines 61 to 74, the
code decodes JSON and accesses nested array keys without checking for JSON
parsing errors or verifying the existence of keys, which can cause warnings. Add
error handling by verifying json_decode did not return null and check that the
expected keys exist before accessing them to prevent warnings and ensure robust
behavior.


$field = GFFormsModel::get_field( $form, $field_id );
if ( empty( $value ) && ! $field->multipleFiles && isset( $_FILES[ $key ] ) && ! empty( $_FILES[ $key ]['name'] ) ) {
$filename = $_FILES[ $key ]['name'];
$attachment_id = $this->get_attachment_id_by_filename( $filename );
if ( $attachment_id ) {
$value = $attachment_id;
}
}
Comment on lines +77 to +83
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 filename validation for security.

The filename from $_FILES should be validated to prevent potential security issues or unexpected behavior.

 if ( empty( $value ) && ! $field->multipleFiles && isset( $_FILES[ $key ] ) && ! empty( $_FILES[ $key ]['name'] ) ) {
 	$filename      = $_FILES[ $key ]['name'];
+	// Validate filename
+	if ( ! preg_match( '/^[a-zA-Z0-9._-]+\.(jpg|jpeg|png|gif|webp)$/i', $filename ) ) {
+		return;
+	}
 	$attachment_id = $this->get_attachment_id_by_filename( $filename );
 	if ( $attachment_id ) {
 		$value = $attachment_id;
 	}
 }
📝 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 ( empty( $value ) && ! $field->multipleFiles && isset( $_FILES[ $key ] ) && ! empty( $_FILES[ $key ]['name'] ) ) {
$filename = $_FILES[ $key ]['name'];
$attachment_id = $this->get_attachment_id_by_filename( $filename );
if ( $attachment_id ) {
$value = $attachment_id;
}
}
if ( empty( $value ) && ! $field->multipleFiles && isset( $_FILES[ $key ] ) && ! empty( $_FILES[ $key ]['name'] ) ) {
$filename = $_FILES[ $key ]['name'];
// Validate filename
if ( ! preg_match( '/^[a-zA-Z0-9._-]+\.(jpg|jpeg|png|gif|webp)$/i', $filename ) ) {
return;
}
$attachment_id = $this->get_attachment_id_by_filename( $filename );
if ( $attachment_id ) {
$value = $attachment_id;
}
}
🤖 Prompt for AI Agents
In gp-media-library/gpml-acf-user-image-field.php around lines 77 to 83, the
filename obtained from $_FILES is used directly without validation, which can
pose security risks. Add validation to the $filename variable to ensure it
contains only safe characters and does not include any path traversal sequences
or other malicious input before using it to get the attachment ID. This can be
done by sanitizing the filename or using a whitelist pattern to allow only
expected characters.


if ( empty( $value ) && ! $this->_args['remove_if_empty'] ) {
return;
}

update_field( $this->_args['meta_key'], $value, 'user_' . $user_id );

}
}


}

# Configuration
Expand Down
Loading