PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/models/FrmEntry.php +80 -14 6.30 → trunk View file →
@@ -348,9 +348,9 @@
348 348 if ( ! $update ) {
349 349 return false;
350 350 }
351 351
352 - $new_values = self::package_entry_to_update( $id, $values );
352 + $new_values = self::package_entry_to_update( $id, $values, $update_type );
353 353 $query_results = $wpdb->update( $wpdb->prefix . 'frm_items', $new_values, compact( 'id' ) );
354 354
355 355 self::after_update_entry( $query_results, $id, $values, $new_values );
356 356
@@ -781,9 +781,9 @@
781 781 if ( $type !== 'xml' ) {
782 782 $values = apply_filters( 'frm_pre_create_entry', $values );
783 783 }
784 784
785 - return self::package_entry_data( $values );
785 + return self::package_entry_data( $values, $type );
786 786 }
787 787
788 788 /**
789 789 * Create an entry and perform after create actions
@@ -838,13 +838,14 @@
838 838 * Prepare the new values for inserting into the database
839 839 *
840 840 * @since 2.0.16
841 841 *
842 - * @param array $values
842 + * @param array $values
843 + * @param string $type The create type. 'xml' for an import.
843 844 *
844 845 * @return array New values.
845 846 */
846 - private static function package_entry_data( &$values ) {
847 + private static function package_entry_data( &$values, $type = 'standard' ) {
847 848 global $wpdb;
848 849
849 850 if ( ! isset( $values['item_key'] ) ) {
850 851 $values['item_key'] = '';
@@ -861,12 +862,12 @@
861 862 'parent_item_id' => (int) self::get_entry_value( $values, 'parent_item_id', 0 ),
862 863 'created_at' => self::get_created_at( $values ),
863 864 'updated_at' => self::get_updated_at( $values ),
864 865 'description' => self::get_entry_description( $values ),
865 - 'user_id' => self::get_entry_user_id( $values ),
866 + 'user_id' => self::get_entry_user_id( $values, $type ),
866 867 );
867 868
868 - $new_values['updated_by'] = $values['updated_by'] ?? $new_values['user_id'];
869 + $new_values['updated_by'] = self::get_updated_by( $values, $type, $new_values['user_id'] );
869 870
870 871 return $new_values;
871 872 }
872 873
@@ -881,8 +882,33 @@
881 882 return $values[ $name ] ?? $default;
882 883 }
883 884
884 885 /**
886 + * Get the updated_by value for an entry.
887 + *
888 + * The submitted value is only used during a trusted import, which restores the user who last
889 + * edited each entry. Every other save is being made by the current user, so a submitted
890 + * updated_by is ignored and cannot be pointed at another account. This matters because
891 + * updated_by is treated as a privilege signal when deciding how much HTML to strip from entry
892 + * values in FrmFieldType::should_strip_most_html().
893 + *
894 + * @since 6.35
895 + *
896 + * @param array $values
897 + * @param string $type The create/update type. 'xml' for an import.
898 + * @param int|string $default The value to use when an import doesn't include updated_by.
899 + *
900 + * @return int
901 + */
902 + private static function get_updated_by( $values, $type, $default ) {
903 + if ( self::is_trusted_import( $type ) ) {
904 + return absint( self::get_entry_value( $values, 'updated_by', $default ) );
905 + }
906 +
907 + return get_current_user_id();
908 + }
909 +
910 + /**
885 911 * Get the ip for a new entry.
886 912 * Allow the import to override the value.
887 913 *
888 914 * @since 2.03.10
@@ -974,14 +1000,15 @@
974 1000 * Get the user_id value for a new entry
975 1001 *
976 1002 * @since 2.0.16
977 1003 *
978 - * @param array $values
1004 + * @param array $values
1005 + * @param string $type The create type. 'xml' for an import.
979 1006 *
980 1007 * @return int
981 1008 */
982 - private static function get_entry_user_id( $values ) {
983 - if ( isset( $values['frm_user_id'] ) && ( is_numeric( $values['frm_user_id'] ) || FrmAppHelper::is_admin() ) ) {
1009 + private static function get_entry_user_id( $values, $type = 'standard' ) {
1010 + if ( isset( $values['frm_user_id'] ) && self::can_set_entry_user_id_from_values( $type ) ) {
984 1011 return $values['frm_user_id'];
985 1012 }
986 1013
987 1014 $current_user_id = get_current_user_id();
@@ -988,8 +1015,46 @@
988 1015 return $current_user_id ? $current_user_id : 0;
989 1016 }
990 1017
991 1018 /**
1019 + * Whether a submitted frm_user_id is allowed to set the entry owner.
1020 + *
1021 + * The owner is only taken from the submitted value when the current user is allowed to manage
1022 + * entries, or during a trusted import that restores each entry's original owner. On a public
1023 + * submission neither is true, so the owner falls back to the current user and cannot be set to
1024 + * another account.
1025 + *
1026 + * @since 6.34
1027 + *
1028 + * @param string $type The create/update type. 'xml' for an import.
1029 + *
1030 + * @return bool
1031 + */
1032 + private static function can_set_entry_user_id_from_values( $type = 'standard' ) {
1033 + if ( self::is_trusted_import( $type ) ) {
1034 + return true;
1035 + }
1036 +
1037 + return current_user_can( 'frm_edit_entries' ) || current_user_can( 'administrator' );
1038 + }
1039 +
1040 + /**
1041 + * Whether an entry is being saved by an import rather than by a normal request.
1042 + *
1043 + * An import is trusted to restore the values stored on each entry, including the columns that
1044 + * are otherwise taken from the current request.
1045 + *
1046 + * @since 6.35
1047 + *
1048 + * @param string $type The create/update type. 'xml' for an import.
1049 + *
1050 + * @return bool
1051 + */
1052 + private static function is_trusted_import( $type = 'standard' ) {
1053 + return 'xml' === $type || ( defined( 'WP_IMPORTING' ) && WP_IMPORTING );
1054 + }
1055 +
1056 + /**
992 1057 * Insert new entry into the database
993 1058 *
994 1059 * @since 2.0.16
995 1060 *
@@ -1168,14 +1233,15 @@
1168 1233 * Package the entry data for updating
1169 1234 *
1170 1235 * @since 2.0.16
1171 1236 *
1172 - * @param int $id
1173 - * @param array $values
1237 + * @param int $id
1238 + * @param array $values
1239 + * @param string $update_type The update type. 'xml' for an import.
1174 1240 *
1175 1241 * @return array New values.
1176 1242 */
1177 - private static function package_entry_to_update( $id, $values ) {
1243 + private static function package_entry_to_update( $id, $values, $update_type = 'standard' ) {
1178 1244 global $wpdb;
1179 1245
1180 1246 $new_values = array(
1181 1247 'name' => FrmAppHelper::truncate( self::get_new_entry_name( $values ), 255, 1, '', true ),
@@ -1181,9 +1247,9 @@
1181 1247 'name' => FrmAppHelper::truncate( self::get_new_entry_name( $values ), 255, 1, '', true ),
1182 1248 'form_id' => (int) self::get_entry_value( $values, 'form_id', null ),
1183 1249 'is_draft' => self::get_is_draft_value( $values ),
1184 1250 'updated_at' => current_time( 'mysql', 1 ),
1185 - 'updated_by' => $values['updated_by'] ?? get_current_user_id(),
1251 + 'updated_by' => self::get_updated_by( $values, $update_type, get_current_user_id() ),
1186 1252 );
1187 1253
1188 1254 if ( isset( $values['post_id'] ) ) {
1189 1255 $new_values['post_id'] = (int) $values['post_id'];
@@ -1196,9 +1262,9 @@
1196 1262 if ( isset( $values['parent_item_id'] ) ) {
1197 1263 $new_values['parent_item_id'] = (int) $values['parent_item_id'];
1198 1264 }
1199 1265
1200 - if ( isset( $values['frm_user_id'] ) && is_numeric( $values['frm_user_id'] ) ) {
1266 + if ( isset( $values['frm_user_id'] ) && is_numeric( $values['frm_user_id'] ) && self::can_set_entry_user_id_from_values( $update_type ) ) {
1201 1267 $new_values['user_id'] = $values['frm_user_id'];
1202 1268 }
1203 1269
1204 1270 return apply_filters( 'frm_update_entry', $new_values, $id );