From 99411c6e3c1da2756ecc906be48acb3d607d2bca Mon Sep 17 00:00:00 2001 From: liviu13 Date: Wed, 1 Oct 2025 15:54:10 +0300 Subject: [PATCH 1/4] add a sql db function that will retrieve a entry and its fields as row columns --- classes/models/FrmEntry.php | 67 +++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/classes/models/FrmEntry.php b/classes/models/FrmEntry.php index bc18eb2bd4..9b8781913d 100644 --- a/classes/models/FrmEntry.php +++ b/classes/models/FrmEntry.php @@ -538,6 +538,73 @@ public static function get_meta( $entry ) { return $entry; } + /** + * Retrieves multiple entries with specified fields pivoted as columns. + * + * Transforms the vertical meta_value structure into a horizontal table format + * where each row represents one entry and each column represents a field value. + * + * Example: + * Instead of: + * item_id | field_id | meta_value + * 100 | 5 | John + * 100 | 6 | john@example.com + * 101 | 5 | Jane + * 101 | 6 | jane@example.com + * + * Returns: + * item_id | name | email + * 100 | John | john@example.com + * 101 | Jane | jane@example.com + * + * @since x.x + * @param array $field_ids_and_aliases The field ids and aliases to get the values for. + * Example: + * array( + * 123 => 'start_range', + * 456 => 'end_range', + * 789 => 'extra_note', + * ) + * This means: + * - Field ID 123 will be returned as column "start_range" + * - Field ID 456 will be returned as column "end_range" + * - Field ID 789 will be returned as column "extra_note". + * + * @param string|array $where The where SQL clause to add to the query. + * + * @return array The entries with the fields pivoted as columns. + */ + public static function get_entries_with_fields( $field_ids_and_aliases, $where = '' ) { + global $wpdb; + + if ( empty( $field_ids_and_aliases ) || ! is_array( $field_ids_and_aliases ) ) { + return array(); + } + + $select_case_parts = array(); + foreach ( $field_ids_and_aliases as $fid => $alias ) { + $select_case_parts[] = $wpdb->prepare( + 'MAX(CASE WHEN field_id = %d THEN meta_value END) AS %i', + absint( $fid ), + $alias + ); + } + + $placeholders = implode( ',', array_fill( 0, count( $field_ids_and_aliases ), '%d' ) ); + $field_id_values = array_map( 'absint', array_keys( $field_ids_and_aliases ) ); + + $sql = ' + SELECT item_id, ' . implode( ', ', $select_case_parts ) . ' + FROM ' . $wpdb->prefix . 'frm_item_metas + WHERE field_id IN ( ' . $placeholders . ' ) + ' . FrmDb::prepend_and_or_where( ' AND ', $where ) . ' + GROUP BY item_id + '; + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + return $wpdb->get_results( $wpdb->prepare( $sql, $field_id_values ) ); + } + /** * @param string $id */ From 05bfe93caef90b7ccec9dfb5a3bdfea74c89ad6b Mon Sep 17 00:00:00 2001 From: liviu13 Date: Wed, 1 Oct 2025 18:16:13 +0300 Subject: [PATCH 2/4] make alias safe --- classes/models/FrmEntry.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/classes/models/FrmEntry.php b/classes/models/FrmEntry.php index 9b8781913d..eb916d717d 100644 --- a/classes/models/FrmEntry.php +++ b/classes/models/FrmEntry.php @@ -583,10 +583,11 @@ public static function get_entries_with_fields( $field_ids_and_aliases, $where = $select_case_parts = array(); foreach ( $field_ids_and_aliases as $fid => $alias ) { + $safe_alias = preg_replace( '/[^a-zA-Z0-9_]/', '', $alias ); $select_case_parts[] = $wpdb->prepare( 'MAX(CASE WHEN field_id = %d THEN meta_value END) AS %i', absint( $fid ), - $alias + $safe_alias ); } From eb51798aa69e37a37abe80ee5f3878803f29892c Mon Sep 17 00:00:00 2001 From: liviu13 Date: Thu, 2 Oct 2025 15:04:47 +0300 Subject: [PATCH 3/4] fix comment order phpcs --- classes/models/FrmEntry.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/models/FrmEntry.php b/classes/models/FrmEntry.php index eb916d717d..fe84e432b0 100644 --- a/classes/models/FrmEntry.php +++ b/classes/models/FrmEntry.php @@ -570,7 +570,7 @@ public static function get_meta( $entry ) { * - Field ID 456 will be returned as column "end_range" * - Field ID 789 will be returned as column "extra_note". * - * @param string|array $where The where SQL clause to add to the query. + * @param array|string $where The where SQL clause to add to the query. * * @return array The entries with the fields pivoted as columns. */ From 269fbbcb6a888767668c44337821f54379e5d188 Mon Sep 17 00:00:00 2001 From: liviu13 Date: Wed, 15 Oct 2025 14:04:12 +0300 Subject: [PATCH 4/4] use sanitike_key instead of preg_replace --- classes/models/FrmEntry.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/classes/models/FrmEntry.php b/classes/models/FrmEntry.php index fe84e432b0..9f727628d4 100644 --- a/classes/models/FrmEntry.php +++ b/classes/models/FrmEntry.php @@ -583,11 +583,10 @@ public static function get_entries_with_fields( $field_ids_and_aliases, $where = $select_case_parts = array(); foreach ( $field_ids_and_aliases as $fid => $alias ) { - $safe_alias = preg_replace( '/[^a-zA-Z0-9_]/', '', $alias ); $select_case_parts[] = $wpdb->prepare( 'MAX(CASE WHEN field_id = %d THEN meta_value END) AS %i', absint( $fid ), - $safe_alias + sanitize_key( $alias ) ); }