PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 1.07.11
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v1.07.11
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/FrmField.php +239 -1150 6.41.07.11 View file →
@@ -1,1168 +1,257 @@
1 1 <?php
2 -if ( ! defined( 'ABSPATH' ) ) {
3 - die( 'You are not allowed to call this page directly.' );
4 -}
2 +if(!defined('ABSPATH')) die(__('You are not allowed to call this page directly.', 'formidable'));
5 3
6 -class FrmField {
4 +if(class_exists('FrmField'))
5 + return;
7 6
8 - public static $use_cache = true;
9 - public static $transient_size = 200;
7 +class FrmField{
10 8
11 - public static function field_selection() {
12 - $frm_settings = FrmAppHelper::get_settings();
13 - $active_captcha = $frm_settings->active_captcha;
14 - if ( ! FrmFieldCaptcha::should_show_captcha() ) {
15 - $captcha_name = 'Captcha';
16 - } elseif ( $active_captcha === 'recaptcha' ) {
17 - $captcha_name = 'reCAPTCHA';
18 - } else {
19 - $captcha_name = 'hCaptcha';
20 - }
21 - $fields = array(
22 - 'text' => array(
23 - 'name' => __( 'Text', 'formidable' ),
24 - 'icon' => 'frm_icon_font frm_text2_icon',
25 - ),
26 - 'textarea' => array(
27 - 'name' => __( 'Paragraph', 'formidable' ),
28 - 'icon' => 'frm_icon_font frm_paragraph_icon',
29 - ),
30 - 'checkbox' => array(
31 - 'name' => __( 'Checkboxes', 'formidable' ),
32 - 'icon' => 'frm_icon_font frm_check_square_icon',
33 - ),
34 - 'radio' => array(
35 - 'name' => __( 'Radio Buttons', 'formidable' ),
36 - 'icon' => 'frm_icon_font frm_radio_checked_icon',
37 - ),
38 - 'select' => array(
39 - 'name' => __( 'Dropdown', 'formidable' ),
40 - 'icon' => 'frm_icon_font frm_caret_square_down_icon',
41 - ),
42 - 'email' => array(
43 - 'name' => __( 'Email', 'formidable' ),
44 - 'icon' => 'frm_icon_font frm_email_icon',
45 - ),
46 - 'url' => array(
47 - 'name' => __( 'Website/URL', 'formidable' ),
48 - 'icon' => 'frm_icon_font frm_link_icon',
49 - ),
50 - 'number' => array(
51 - 'name' => __( 'Number', 'formidable' ),
52 - 'icon' => 'frm_icon_font frm_hashtag_icon',
53 - ),
54 - 'name' => array(
55 - 'name' => __( 'Name', 'formidable' ),
56 - 'icon' => 'frm_icon_font frm_user_name_icon',
57 - ),
58 - 'phone' => array(
59 - 'name' => __( 'Phone', 'formidable' ),
60 - 'icon' => 'frm_icon_font frm_phone_icon',
61 - ),
62 - 'html' => array(
63 - 'name' => __( 'HTML', 'formidable' ),
64 - 'icon' => 'frm_icon_font frm_code_icon',
65 - ),
66 - 'hidden' => array(
67 - 'name' => __( 'Hidden', 'formidable' ),
68 - 'icon' => 'frm_icon_font frm_eye_slash_icon',
69 - ),
70 - 'user_id' => array(
71 - 'name' => __( 'User ID', 'formidable' ),
72 - 'icon' => 'frm_icon_font frm_user_icon',
73 - ),
74 - 'captcha' => array(
75 - 'name' => $captcha_name,
76 - 'icon' => 'frm_icon_font frm_shield_check_icon',
77 - ),
78 - );
9 + function create( $values, $return=true ){
10 + global $wpdb;
79 11
80 - return apply_filters( 'frm_available_fields', $fields );
81 - }
12 + $new_values = array();
13 + $key = isset($values['field_key']) ? $values['field_key'] : $values['name'];
14 + $new_values['field_key'] = FrmAppHelper::get_unique_key($key, $wpdb->prefix .'frm_fields', 'field_key');
82 15
83 - public static function pro_field_selection() {
84 - $images_url = FrmAppHelper::plugin_url() . '/images/';
85 - $fields = array(
86 - 'file' => array(
87 - 'name' => __( 'File Upload', 'formidable' ),
88 - 'icon' => 'frm_icon_font frm_upload_icon',
89 - 'message' => 'Add file uploads to save time and cut down on back-and-forth. Upgrade to Pro to get Upload fields and more.',
90 - ),
91 - 'rte' => array(
92 - 'name' => __( 'Rich Text', 'formidable' ),
93 - 'icon' => 'frm_icon_font frm_align_right_icon',
94 - ),
95 - 'date' => array(
96 - 'name' => __( 'Date', 'formidable' ),
97 - 'icon' => 'frm_icon_font frm_calendar_icon',
98 - ),
99 - 'time' => array(
100 - 'name' => __( 'Time', 'formidable' ),
101 - 'icon' => 'frm_icon_font frm_clock_icon',
102 - ),
103 - 'scale' => array(
104 - 'name' => __( 'Scale', 'formidable' ),
105 - 'icon' => 'frm_icon_font frm_linear_scale_icon',
106 - 'message' => 'Add a set of radio buttons with whatever range you choose. <img src="' . esc_attr( $images_url ) . 'scale_field.png" alt="Scale Field" />',
107 - ),
108 - 'star' => array(
109 - 'name' => __( 'Star Rating', 'formidable' ),
110 - 'icon' => 'frm_icon_font frm_star_icon',
111 - ),
112 - 'range' => array(
113 - 'name' => __( 'Slider', 'formidable' ),
114 - 'icon' => 'frm_icon_font frm_code_commit_icon',
115 - ),
116 - 'toggle' => array(
117 - 'name' => __( 'Toggle', 'formidable' ),
118 - 'icon' => 'frm_icon_font frm_toggle_on_icon',
119 - ),
120 - 'data' => array(
121 - 'name' => __( 'Dynamic', 'formidable' ),
122 - 'icon' => 'frm_icon_font frm_sitemap_icon',
123 - 'message' => 'Create relationships between multiple forms. You can link a member to a team, a rating to a product, a comment to a submission, and much more.',
124 - ),
125 - 'lookup' => array(
126 - 'name' => __( 'Lookup', 'formidable' ),
127 - 'icon' => 'frm_icon_font frm_search_icon',
128 - 'message' => 'Filter the options in the next field and automatically add values to other fields. Upgrade to Pro to get Lookup fields and more. <img src="' . esc_attr( $images_url ) . 'look-up_year-make-model.gif" alt="cascading lookup fields" />',
129 - ),
130 - 'divider|repeat' => array(
131 - 'name' => __( 'Repeater', 'formidable' ),
132 - 'icon' => 'frm_icon_font frm_repeater_icon',
133 - 'message' => 'Allow your visitors to add new sets of fields while filling out forms. Increase conversions while saving building time and server resources. <img src="' . esc_attr( $images_url ) . 'repeatable-section_frontend.gif" alt="Dynamically Add Form Fields with repeatable sections" />',
134 - ),
135 - 'end_divider' => array(
136 - 'name' => __( 'Section Buttons', 'formidable' ),
137 - 'switch_from' => 'divider',
138 - ),
139 - 'divider' => array(
140 - 'name' => __( 'Section', 'formidable' ),
141 - 'icon' => 'frm_icon_font frm_header_icon',
142 - ),
143 - 'break' => array(
144 - 'name' => __( 'Page Break', 'formidable' ),
145 - 'icon' => 'frm_icon_font frm_page_break_icon',
146 - 'message' => 'Get multi-paged forms with progress bars. Did you know you can upgrade to PRO to unlock multi-step forms with more awesome features?',
147 - ),
148 - 'form' => array(
149 - 'name' => __( 'Embed Form', 'formidable' ),
150 - 'icon' => 'frm_icon_font frm_file_text_icon',
151 - ),
152 - 'likert' => array(
153 - 'name' => __( 'Likert Scale', 'formidable' ),
154 - 'icon' => 'frm_icon_font frm_likert_scale frm_show_upgrade',
155 - 'addon' => 'surveys',
156 - ),
157 - 'nps' => array(
158 - 'name' => __( 'NPS', 'formidable' ),
159 - 'icon' => 'frm_icon_font frm_nps frm_show_upgrade',
160 - 'addon' => 'surveys',
161 - ),
162 - 'password' => array(
163 - 'name' => __( 'Password', 'formidable' ),
164 - 'icon' => 'frm_icon_font frm_lock_open_icon',
165 - ),
166 - 'tag' => array(
167 - 'name' => __( 'Tags', 'formidable' ),
168 - 'icon' => 'frm_icon_font frm_price_tags_icon',
169 - ),
170 - 'credit_card' => array(
171 - 'name' => __( 'Credit Card', 'formidable' ),
172 - 'icon' => 'frm_icon_font frm_credit_card_icon frm_show_upgrade',
173 - 'addon' => 'stripe',
174 - ),
175 - 'address' => array(
176 - 'name' => __( 'Address', 'formidable' ),
177 - 'icon' => 'frm_icon_font frm_location_icon',
178 - ),
179 - 'summary' => array(
180 - 'name' => __( 'Summary', 'formidable' ),
181 - 'icon' => 'frm_icon_font frm_file_text_icon',
182 - 'message' => 'Allow visitors to review their responses before a form is submitted. Upgrade to Pro to get Summary fields and more.',
183 - ),
184 - 'signature' => array(
185 - 'name' => __( 'Signature', 'formidable' ),
186 - 'icon' => 'frm_icon_font frm_signature_icon frm_show_upgrade',
187 - 'addon' => 'signature',
188 - ),
189 - 'ai' => array(
190 - 'name' => __( 'AI', 'formidable' ),
191 - 'icon' => 'frm_icon_font frm_eye_icon frm_show_upgrade',
192 - 'addon' => 'ai',
193 - 'message' => 'Streamline workflows and reclaim valuable time with the power of AI. You can effortlessly respond to your visitors in real-time with ChatGPT as your automated assistant. Upgrade to Pro and unlock AI-powered fields.',
194 - ),
195 - 'ssa-appointment' => array(
196 - 'name' => __( 'Appointment', 'formidable' ),
197 - 'icon' => 'frm_icon_font frm_calendar_icon frm_show_upgrade',
198 - 'require' => 'Simply Schedule Appointments',
199 - 'message' => 'Appointment fields are an integration with <a href="https://simplyscheduleappointments.com/meet/formidable/">Simply Schedule Appointments</a>. Get started now to schedule appointments directly from your forms.
200 - <img src="' . esc_attr( $images_url ) . 'appointments.png" alt="Scheduling" />',
201 - 'link' => 'https://simplyscheduleappointments.com/meet/formidable/',
202 - ),
203 - 'product' => array(
204 - 'name' => __( 'Product', 'formidable' ),
205 - 'icon' => 'frm_icon_font frm_product_icon',
206 - 'section' => 'pricing',
207 - ),
208 - 'quantity' => array(
209 - 'name' => __( 'Quantity', 'formidable' ),
210 - 'icon' => 'frm_icon_font frm_quantity_icon',
211 - 'section' => 'pricing',
212 - ),
213 - 'total' => array(
214 - 'name' => __( 'Total', 'formidable' ),
215 - 'icon' => 'frm_icon_font frm_total_icon',
216 - 'section' => 'pricing',
217 - ),
218 - );
16 + foreach ( array('name', 'description', 'type', 'default_value') as $col ) {
17 + $new_values[$col] = $values[$col];
18 + }
19 +
20 + $new_values['options'] = $values['options'];
219 21
220 - if ( ! FrmAppHelper::show_new_feature( 'ai' ) ) {
221 - unset( $fields['ai'] );
222 - }
22 + $new_values['field_order'] = isset($values['field_order']) ? (int)$values['field_order'] : NULL;
23 + $new_values['required'] = isset($values['required']) ? (int)$values['required'] : 0;
24 + $new_values['form_id'] = isset($values['form_id']) ? (int)$values['form_id'] : NULL;
25 + $new_values['field_options'] = $values['field_options'];
26 + $new_values['created_at'] = current_time('mysql', 1);
27 + if(isset($values['id'])){
28 + global $frm_duplicate_ids;
29 + $frm_duplicate_ids[$values['field_key']] = $new_values['field_key'];
30 + $new_values = apply_filters('frm_duplicated_field', $new_values);
31 + }
32 +
33 + foreach($new_values as $k => $v){
34 + if(is_array($v))
35 + $new_values[$k] = serialize($v);
36 + unset($k);
37 + unset($v);
38 + }
39 +
40 + //if(isset($values['id']) and is_numeric($values['id']))
41 + // $new_values['id'] = $values['id'];
42 +
43 + $query_results = $wpdb->insert( $wpdb->prefix .'frm_fields', $new_values );
44 + if($return){
45 + if($query_results){
46 + delete_transient('frm_all_form_fields_'. $new_values['form_id']);
47 + $new_id = $wpdb->insert_id;
48 + if(isset($values['id']))
49 + $frm_duplicate_ids[$values['id']] = $new_id;
50 + return $new_id;
51 + }else{
52 + return false;
53 + }
54 + }
55 + }
223 56
224 - // Since the signature field may be in a different section, don't show it twice.
225 - $lite_fields = self::field_selection();
226 - if ( isset( $lite_fields['signature'] ) ) {
227 - unset( $fields['signature'] );
228 - }
57 + function duplicate($old_form_id, $form_id, $copy_keys=false, $blog_id=false){
58 + global $frm_duplicate_ids, $wpdb;
59 + $fields = $this->getAll(array('fi.form_id' => $old_form_id), 'field_order', '', $blog_id);
60 + foreach ((array)$fields as $field){
61 + $values = array();
62 + $new_key = ($copy_keys) ? $field->field_key : '';
63 + if($copy_keys and substr($field->field_key, -1) == 2)
64 + $new_key = rtrim($new_key, 2);
65 + $values['field_key'] = FrmAppHelper::get_unique_key($new_key, $wpdb->prefix .'frm_fields', 'field_key');
66 + $values['options'] = maybe_serialize($field->options);
67 + $values['form_id'] = $form_id;
68 + foreach (array('name', 'description', 'type', 'default_value', 'field_order', 'required', 'field_options') as $col)
69 + $values[$col] = $field->{$col};
70 + $values = apply_filters('frm_duplicated_field', $values);
71 + $new_id = $this->create($values);
72 + $frm_duplicate_ids[$field->id] = $new_id;
73 + $frm_duplicate_ids[$field->field_key] = $new_id;
74 + unset($field);
75 + }
76 + }
229 77
230 - return apply_filters( 'frm_pro_available_fields', $fields );
231 - }
78 + function update( $id, $values ){
79 + global $wpdb;
80 +
81 + if (isset($values['field_key']))
82 + $values['field_key'] = FrmAppHelper::get_unique_key($values['field_key'], $wpdb->prefix .'frm_fields', 'field_key', $id);
232 83
233 - /**
234 - * @since 4.0
235 - */
236 - public static function all_field_selection() {
237 - $pro_field_selection = self::pro_field_selection();
238 - return array_merge( $pro_field_selection, self::field_selection() );
239 - }
84 + if ( isset($values['required']) ) {
85 + $values['required'] = (int) $values['required'];
86 + }
87 +
88 + if (isset($values['default_value']) and is_array($values['default_value']))
89 + $values['default_value'] = serialize($values['default_value']);
90 +
91 + if (isset($values['field_options']) and is_array($values['field_options']))
92 + $values['field_options'] = serialize($values['field_options']);
93 +
94 + if (isset($values['options']) and is_array($values['options']))
95 + $values['options'] = serialize($values['options']);
96 +
97 + $query_results = $wpdb->update( $wpdb->prefix .'frm_fields', $values, array( 'id' => $id ) );
98 +
99 + if(isset($values['form_id'])){
100 + $form_id = $values['form_id'];
101 + }else{
102 + $field = $this->getOne($id);
103 + if($field)
104 + $form_id = $field->form_id;
105 + unset($field);
106 + }
107 + unset($values);
108 +
109 + if($query_results){
110 + wp_cache_delete( $id, 'frm_field' );
111 + delete_transient('frm_all_form_fields_'. $form_id);
112 + }
113 +
114 + return $query_results;
115 + }
240 116
241 - public static function create( $values, $return = true ) {
242 - global $wpdb, $frm_duplicate_ids;
117 + function destroy( $id ){
118 + global $wpdb;
243 119
244 - $new_values = array();
245 - $key = isset( $values['field_key'] ) ? $values['field_key'] : $values['name'];
246 - $new_values['field_key'] = FrmAppHelper::get_unique_key( $key, $wpdb->prefix . 'frm_fields', 'field_key' );
120 + do_action('frm_before_destroy_field', $id);
121 + do_action('frm_before_destroy_field_'. $id);
122 +
123 + wp_cache_delete( $id, 'frm_field' );
124 + $field = $this->getOne($id);
125 + if ( !$field ) {
126 + return false;
127 + }
128 +
129 + delete_transient('frm_all_form_fields_'. $field->form_id);
130 +
131 + $wpdb->query("DELETE FROM {$wpdb->prefix}frm_item_metas WHERE field_id='$id'");
132 + return $wpdb->query("DELETE FROM {$wpdb->prefix}frm_fields WHERE id='$id'");
133 + }
247 134
248 - $values = FrmAppHelper::maybe_filter_array( $values, array( 'name', 'description' ) );
135 + function getOne( $id ){
136 + global $wpdb;
137 + $results = wp_cache_get( $id, 'frm_field' );
138 + if(!$results){
139 +
140 + $where = (is_numeric($id)) ? 'id=%d' : 'field_key=%s';
141 + $results = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}frm_fields WHERE $where", $id));
142 +
143 + if($results){
144 + wp_cache_set( $results->id, $results, 'frm_field' );
145 + wp_cache_set( $results->field_key, $results, 'frm_field' );
146 + }
147 + }
148 +
149 + if($results){
150 + $results->field_options = maybe_unserialize($results->field_options);
151 + if(isset($results->field_options['format']) and !empty($results->field_options['format']))
152 + $results->field_options['format'] = addslashes($results->field_options['format']);
153 + $results->options = maybe_unserialize($results->options);
154 + $results->default_value = maybe_unserialize($results->default_value);
155 + }
156 +
157 + return stripslashes_deep($results);
158 + }
249 159
250 - foreach ( array( 'name', 'description', 'type', 'default_value' ) as $col ) {
251 - $new_values[ $col ] = $values[ $col ];
252 - }
160 + function getAll($where=array(), $order_by = '', $limit = '', $blog_id=false){
161 + global $wpdb;
162 +
163 + if ($blog_id and is_multisite()){
164 + global $wpmuBaseTablePrefix;
165 + if($wpmuBaseTablePrefix)
166 + $prefix = "{$wpmuBaseTablePrefix}{$blog_id}_";
167 + else
168 + $prefix = $wpdb->get_blog_prefix( $blog_id );
169 +
170 + $table_name = "{$prefix}frm_fields";
171 + $form_table_name = "{$prefix}frm_forms";
172 + }else{
173 + $table_name = $wpdb->prefix .'frm_fields';
174 + $form_table_name = $wpdb->prefix .'frm_forms';
175 + }
176 +
177 + if(!empty($order_by) and !preg_match("/ORDER BY/", $order_by))
178 + $order_by = " ORDER BY {$order_by}";
253 179
254 - $new_values['options'] = self::maybe_filter_options( $values['options'] );
255 - $new_values['field_order'] = isset( $values['field_order'] ) ? (int) $values['field_order'] : null;
256 - $new_values['required'] = isset( $values['required'] ) ? (int) $values['required'] : 0;
257 - $new_values['form_id'] = isset( $values['form_id'] ) ? (int) $values['form_id'] : null;
258 - $new_values['field_options'] = $values['field_options'];
259 - $new_values['created_at'] = current_time( 'mysql', 1 );
180 + if(is_numeric($limit))
181 + $limit = " LIMIT {$limit}";
182 +
183 + $query = "SELECT fi.*, fr.name as form_name FROM {$table_name} fi LEFT OUTER JOIN {$form_table_name} fr ON fi.form_id=fr.id";
184 + $old_where = $where;
185 + if(is_array($where)){
186 + global $frmdb;
187 + extract($frmdb->get_where_clause_and_values( $where ));
260 188
261 - if ( isset( $values['id'] ) ) {
262 - $frm_duplicate_ids[ $values['field_key'] ] = $new_values['field_key'];
263 - $new_values = apply_filters( 'frm_duplicated_field', $new_values );
264 - }
189 + $query .= "{$where}{$order_by}{$limit}";
190 + $query = $wpdb->prepare($query, $values);
191 + }else{
192 + $query .= FrmAppHelper::prepend_and_or_where(' WHERE ', $where) . $order_by . $limit;
193 + }
194 +
195 + if ($limit == ' LIMIT 1' or $limit == 1){
196 + $results = $wpdb->get_row($query);
197 + }else{
198 + $ak = is_array($old_where) ? array_keys($old_where) : $old_where;
199 + if($order_by == ' ORDER BY field_order' and empty($limit) and empty($blog_id) and is_array($old_where) and count($old_where) == 1 and reset($ak) == 'fi.form_id'){
200 + $save_cache = true;
201 + $results = get_transient('frm_all_form_fields_'. reset($old_where));
202 + if($results and (is_array($results) or is_object($results)))
203 + $cached = true;
204 + }
205 + unset($ak);
206 + if(!isset($cached))
207 + $results = $wpdb->get_results($query);
208 + }
209 +
210 + if($results and !isset($cached)){
211 + if(is_array($results)){
212 + foreach($results as $r_key => $result){
213 + wp_cache_set($result->id, $result, 'frm_field');
214 + wp_cache_set($result->field_key, $result, 'frm_field');
215 + $results[$r_key]->field_options = maybe_unserialize($result->field_options);
216 + if(isset($results[$r_key]->field_options['format']) and !empty($results[$r_key]->field_options['format']))
217 + $results[$r_key]->field_options['format'] = addslashes($results[$r_key]->field_options['format']);
218 + $results[$r_key]->options = maybe_unserialize($result->options);
219 + $results[$r_key]->default_value = maybe_unserialize($result->default_value);
220 + $form_id = $result->form_id;
221 +
222 + unset($r_key, $result);
223 + }
224 + if(isset($save_cache))
225 + set_transient('frm_all_form_fields_'. $form_id, $results, 60*60*6);
226 + unset($form_id);
227 + }else{
228 + wp_cache_set($results->id, $results, 'frm_field');
229 + wp_cache_set($results->field_key, $results, 'frm_field');
230 + $results->field_options = maybe_unserialize($results->field_options);
231 + if(isset($results->field_options['format']) and !empty($results->field_options['format']))
232 + $results->field_options['format'] = addslashes($results->field_options['format']);
233 + $results->options = maybe_unserialize($results->options);
234 + $results->default_value = maybe_unserialize($results->default_value);
235 + }
236 + }
237 +
238 + return stripslashes_deep($results);
239 + }
265 240
266 - self::preserve_format_option_backslashes( $new_values );
267 -
268 - foreach ( $new_values as $k => $v ) {
269 - if ( is_array( $v ) ) {
270 - if ( $k === 'default_value' ) {
271 - $new_values[ $k ] = FrmAppHelper::maybe_json_encode( $v );
272 - } else {
273 - $new_values[ $k ] = serialize( $v );
274 - }
275 - }
276 - unset( $k, $v );
277 - }
278 -
279 - $query_results = $wpdb->insert( $wpdb->prefix . 'frm_fields', $new_values );
280 - $new_id = 0;
281 - if ( $query_results ) {
282 - self::delete_form_transient( $new_values['form_id'] );
283 - $new_id = $wpdb->insert_id;
284 - }
285 -
286 - if ( ! $return ) {
287 - return false;
288 - }
289 -
290 - if ( $query_results ) {
291 - if ( isset( $values['id'] ) ) {
292 - $frm_duplicate_ids[ $values['id'] ] = $new_id;
293 - }
294 -
295 - return $new_id;
296 - } else {
297 - return false;
298 - }
299 - }
300 -
301 - /**
302 - * @since 5.0.08
303 - *
304 - * @param array $options
305 - * @return array
306 - */
307 - private static function maybe_filter_options( $options ) {
308 - return FrmAppHelper::maybe_filter_array( $options, array( 'custom_html' ) );
309 - }
310 -
311 - /**
312 - * Process the field duplication.
313 - *
314 - * @since 5.0.05
315 - */
316 - public static function duplicate_single_field( $field_id, $form_id ) {
317 - $copy_field = self::getOne( $field_id );
318 - if ( ! $copy_field ) {
319 - return false;
320 - }
321 -
322 - do_action( 'frm_duplicate_field', $copy_field, $form_id );
323 - do_action( 'frm_duplicate_field_' . $copy_field->type, $copy_field, $form_id );
324 -
325 - $values = array(
326 - 'id' => $copy_field->id,
327 - );
328 - FrmFieldsHelper::fill_field( $values, $copy_field, $copy_field->form_id );
329 - $values = apply_filters( 'frm_prepare_single_field_for_duplication', $values );
330 -
331 - $field_id = self::create( $values );
332 -
333 - /**
334 - * Fires after duplicating a field.
335 - *
336 - * @since 5.0.04
337 - *
338 - * @param array $args {
339 - * The arguments.
340 - *
341 - * @type int $field_id New field ID.
342 - * @type array $values Values before inserting.
343 - * @type object $copy_field Copy field data.
344 - * @type int $form_id Form ID.
345 - * }
346 - */
347 - do_action( 'frm_after_duplicate_field', compact( 'field_id', 'values', 'copy_field', 'form_id' ) );
348 -
349 - return compact( 'field_id', 'values' );
350 - }
351 -
352 - public static function duplicate( $old_form_id, $form_id, $copy_keys = false, $blog_id = false ) {
353 - global $frm_duplicate_ids;
354 -
355 - $where = array(
356 - array(
357 - 'or' => 1,
358 - 'fi.form_id' => $old_form_id,
359 - 'fr.parent_form_id' => $old_form_id,
360 - ),
361 - );
362 - $fields = self::getAll( $where, 'field_order', '', $blog_id );
363 -
364 - foreach ( (array) $fields as $field ) {
365 - $new_key = $copy_keys ? $field->field_key : '';
366 - if ( $copy_keys && substr( $field->field_key, - 1 ) == 2 ) {
367 - $new_key = rtrim( $new_key, 2 );
368 - }
369 -
370 - $values = array();
371 - FrmFieldsHelper::fill_field( $values, $field, $form_id, $new_key );
372 -
373 - // If this is a repeating section, create new form
374 - if ( self::is_repeating_field( $field ) ) {
375 - // create the repeatable form
376 - $new_repeat_form_id = apply_filters(
377 - 'frm_create_repeat_form',
378 - 0,
379 - array(
380 - 'parent_form_id' => $form_id,
381 - 'field_name' => $field->name,
382 - )
383 - );
384 -
385 - // Save old form_select
386 - $old_repeat_form_id = $field->field_options['form_select'];
387 -
388 - // Update form_select for repeating field
389 - $values['field_options']['form_select'] = $new_repeat_form_id;
390 - }
391 -
392 - // If this is a field inside of a repeating section, associate it with the correct form
393 - if ( $field->form_id != $old_form_id && isset( $old_repeat_form_id ) && isset( $new_repeat_form_id ) && $field->form_id == $old_repeat_form_id ) {
394 - $values['form_id'] = $new_repeat_form_id;
395 - }
396 -
397 - $values['description'] = FrmFieldsHelper::switch_field_ids( $values['description'] );
398 -
399 - $values = apply_filters( 'frm_duplicated_field', $values );
400 - $new_id = self::create( $values );
401 - $frm_duplicate_ids[ $field->id ] = $new_id;
402 - $frm_duplicate_ids[ $field->field_key ] = $new_id;
403 - unset( $field );
404 - }
405 - }
406 -
407 - public static function update( $id, $values ) {
408 - global $wpdb;
409 -
410 - $id = absint( $id );
411 - $values = FrmAppHelper::maybe_filter_array( $values, array( 'name', 'description' ) );
412 -
413 - if ( isset( $values['field_key'] ) ) {
414 - $values['field_key'] = FrmAppHelper::get_unique_key( $values['field_key'], $wpdb->prefix . 'frm_fields', 'field_key', $id );
415 - }
416 -
417 - if ( isset( $values['required'] ) ) {
418 - $values['required'] = (int) $values['required'];
419 - }
420 -
421 - self::preserve_format_option_backslashes( $values );
422 -
423 - if ( isset( $values['type'] ) ) {
424 - $values = apply_filters( 'frm_clean_' . $values['type'] . '_field_options_before_update', $values );
425 -
426 - if ( $values['type'] === 'hidden' && isset( $values['field_options'] ) && isset( $values['field_options']['clear_on_focus'] ) ) {
427 - // don't keep the old placeholder setting for hidden fields
428 - $values['field_options']['clear_on_focus'] = 0;
429 - }
430 - }
431 -
432 - // serialize array values
433 - foreach ( array( 'field_options', 'options' ) as $opt ) {
434 - if ( isset( $values[ $opt ] ) && is_array( $values[ $opt ] ) ) {
435 - if ( 'field_options' === $opt ) {
436 - $values[ $opt ] = self::maybe_filter_options( $values[ $opt ] );
437 - }
438 - $values[ $opt ] = serialize( $values[ $opt ] );
439 - }
440 - }
441 - if ( isset( $values['default_value'] ) && is_array( $values['default_value'] ) ) {
442 - $values['default_value'] = json_encode( $values['default_value'] );
443 - }
444 -
445 - $query_results = $wpdb->update( $wpdb->prefix . 'frm_fields', $values, array( 'id' => $id ) );
446 -
447 - $form_id = 0;
448 - if ( isset( $values['form_id'] ) ) {
449 - $form_id = absint( $values['form_id'] );
450 - } else {
451 - $field = self::getOne( $id );
452 - if ( $field ) {
453 - $form_id = $field->form_id;
454 - }
455 - unset( $field );
456 - }
457 - unset( $values );
458 -
459 - if ( $query_results ) {
460 - wp_cache_delete( $id, 'frm_field' );
461 - if ( $form_id ) {
462 - self::delete_form_transient( $form_id );
463 - }
464 - }
465 -
466 - return $query_results;
467 - }
468 -
469 - /**
470 - * Keep backslashes in the phone format option
471 - *
472 - * @since 2.0.8
473 - *
474 - * @param $values array - pass by reference
475 - */
476 - private static function preserve_format_option_backslashes( &$values ) {
477 - if ( isset( $values['field_options']['format'] ) ) {
478 - $values['field_options']['format'] = FrmAppHelper::preserve_backslashes( $values['field_options']['format'] );
479 - }
480 - }
481 -
482 - public static function destroy( $id ) {
483 - global $wpdb;
484 -
485 - do_action( 'frm_before_destroy_field', $id );
486 -
487 - wp_cache_delete( $id, 'frm_field' );
488 - $field = self::getOne( $id );
489 - if ( ! $field ) {
490 - return false;
491 - }
492 -
493 - self::delete_form_transient( $field->form_id );
494 -
495 - $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_item_metas WHERE field_id=%d', $id ) );
496 -
497 - return $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_fields WHERE id=%d', $id ) );
498 - }
499 -
500 - public static function delete_form_transient( $form_id ) {
501 - $form_id = absint( $form_id );
502 - delete_transient( 'frm_form_fields_' . $form_id . 'excludeinclude' );
503 - delete_transient( 'frm_form_fields_' . $form_id . 'includeinclude' );
504 - delete_transient( 'frm_form_fields_' . $form_id . 'includeexclude' );
505 - delete_transient( 'frm_form_fields_' . $form_id . 'excludeexclude' );
506 -
507 - global $wpdb;
508 - $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->options . ' WHERE option_name LIKE %s OR option_name LIKE %s OR option_name LIKE %s OR option_name LIKE %s', '_transient_timeout_frm_form_fields_' . $form_id . 'ex%', '_transient_frm_form_fields_' . $form_id . 'ex%', '_transient_timeout_frm_form_fields_' . $form_id . 'in%', '_transient_frm_form_fields_' . $form_id . 'in%' ) );
509 -
510 - FrmDb::cache_delete_group( 'frm_field' );
511 -
512 - $form = FrmForm::getOne( $form_id );
513 - if ( $form && $form->parent_form_id && $form->parent_form_id != $form_id ) {
514 - self::delete_form_transient( $form->parent_form_id );
515 - }
516 - }
517 -
518 - /**
519 - * If $field is numeric, get the field object
520 - */
521 - public static function maybe_get_field( &$field ) {
522 - if ( ! is_object( $field ) ) {
523 - $field = self::getOne( $field );
524 - }
525 - }
526 -
527 - /**
528 - * @param string|int $id The field id or key.
529 - * @param bool $filter When true, run the frm_field filter.
530 - */
531 - public static function getOne( $id, $filter = false ) {
532 - if ( empty( $id ) ) {
533 - return null;
534 - }
535 -
536 - global $wpdb;
537 -
538 - $where = is_numeric( $id ) ? 'id=%d' : 'field_key=%s';
539 - $query = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . 'frm_fields WHERE ' . $where, $id ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
540 -
541 - $results = FrmDb::check_cache( $id, 'frm_field', $query, 'get_row', 0 );
542 -
543 - if ( empty( $results ) ) {
544 - self::filter_field( $filter, $results );
545 - return $results;
546 - }
547 -
548 - if ( is_numeric( $id ) ) {
549 - FrmDb::set_cache( $results->field_key, $results, 'frm_field' );
550 - } elseif ( $results ) {
551 - FrmDb::set_cache( $results->id, $results, 'frm_field' );
552 - }
553 -
554 - self::prepare_options( $results );
555 - self::filter_field( $filter, $results );
556 -
557 - return wp_unslash( $results );
558 - }
559 -
560 - /**
561 - * @since 3.06.01
562 - * @param bool $filter When true, run the frm_field filter.
563 - * @param object $results
564 - */
565 - private static function filter_field( $filter, &$results ) {
566 - if ( $filter ) {
567 - /**
568 - * @since 3.06.01
569 - */
570 - $results = apply_filters( 'frm_field', $results );
571 - }
572 - }
573 -
574 - /**
575 - * Get the field type by key or id
576 - *
577 - * @param int|string The field id or key
578 - * @param mixed $col The name of the column in the fields database table
579 - */
580 - public static function get_type( $id, $col = 'type' ) {
581 - $field = FrmDb::check_cache( $id, 'frm_field' );
582 - if ( $field ) {
583 - $type = $field->{$col};
584 - } else {
585 - $where = array(
586 - 'or' => 1,
587 - 'id' => $id,
588 - 'field_key' => $id,
589 - );
590 - $type = FrmDb::get_var( 'frm_fields', $where, $col );
591 - }
592 -
593 - return $type;
594 - }
595 -
596 - public static function get_all_types_in_form( $form_id, $type, $limit = '', $inc_sub = 'exclude' ) {
597 - if ( ! $form_id ) {
598 - return array();
599 - }
600 -
601 - $results = self::get_fields_from_transients(
602 - $form_id,
603 - array(
604 - 'inc_embed' => $inc_sub,
605 - 'inc_repeat' => $inc_sub,
606 - )
607 - );
608 - if ( ! empty( $results ) ) {
609 - $fields = array();
610 - $count = 0;
611 - foreach ( $results as $result ) {
612 - if ( $type != $result->type ) {
613 - continue;
614 - }
615 -
616 - $fields[ $result->id ] = $result;
617 - $count ++;
618 - if ( $limit == 1 ) {
619 - $fields = $result;
620 - break;
621 - }
622 -
623 - if ( ! empty( $limit ) && $count >= $limit ) {
624 - break;
625 - }
626 -
627 - unset( $result );
628 - }
629 -
630 - return wp_unslash( $fields );
631 - }
632 -
633 - self::$use_cache = false;
634 -
635 - $where = array(
636 - 'fi.form_id' => (int) $form_id,
637 - 'fi.type' => $type,
638 - );
639 - self::maybe_include_repeating_fields( $inc_sub, $where );
640 - $results = self::getAll( $where, 'field_order', $limit );
641 - self::$use_cache = true;
642 - self::include_sub_fields( $results, $inc_sub, $type, $form_id );
643 -
644 - return $results;
645 - }
646 -
647 - public static function get_all_for_form( $form_id, $limit = '', $inc_embed = 'exclude', $inc_repeat = 'include' ) {
648 - if ( ! (int) $form_id ) {
649 - return array();
650 - }
651 -
652 - $results = self::get_fields_from_transients( $form_id, compact( 'inc_embed', 'inc_repeat' ) );
653 - if ( ! empty( $results ) ) {
654 - if ( empty( $limit ) ) {
655 - return $results;
656 - }
657 -
658 - $fields = array();
659 - $count = 0;
660 - foreach ( $results as $result ) {
661 - $count ++;
662 - $fields[ $result->id ] = $result;
663 - if ( ! empty( $limit ) && $count >= $limit ) {
664 - break;
665 - }
666 - }
667 -
668 - return $fields;
669 - }
670 -
671 - self::$use_cache = false;
672 -
673 - $where = array( 'fi.form_id' => absint( $form_id ) );
674 - self::maybe_include_repeating_fields( $inc_repeat, $where );
675 - $results = self::getAll( $where, 'field_order', $limit );
676 -
677 - self::$use_cache = true;
678 -
679 - self::include_sub_fields( $results, $inc_embed, 'all', $form_id );
680 -
681 - if ( empty( $limit ) ) {
682 - self::set_field_transient( $results, $form_id, 0, compact( 'inc_embed', 'inc_repeat' ) );
683 - }
684 -
685 - return $results;
686 - }
687 -
688 - /**
689 - * If repeating fields should be included, adjust $where accordingly
690 - *
691 - * @param string $inc_repeat
692 - * @param array $where - pass by reference
693 - */
694 - private static function maybe_include_repeating_fields( $inc_repeat, &$where ) {
695 - if ( $inc_repeat == 'include' ) {
696 - $form_id = $where['fi.form_id'];
697 - $where[] = array(
698 - 'or' => 1,
699 - 'fi.form_id' => $form_id,
700 - 'fr.parent_form_id' => $form_id,
701 - );
702 - unset( $where['fi.form_id'] );
703 - }
704 - }
705 -
706 - public static function include_sub_fields( &$results, $inc_embed, $type = 'all', $form_id = '' ) {
707 - $no_sub_forms = empty( $results ) && $type === 'all';
708 - if ( 'include' != $inc_embed || $no_sub_forms ) {
709 - return;
710 - }
711 -
712 - $form_fields = $results;
713 - $should_get_subforms = ( $type !== 'all' && $type !== 'form' && ! empty( $form_id ) );
714 - if ( $should_get_subforms ) {
715 - $form_fields = self::get_all_types_in_form( $form_id, 'form' );
716 - }
717 -
718 - $index_offset = 1;
719 - foreach ( $form_fields as $k => $field ) {
720 - if ( 'form' != $field->type || ! isset( $field->field_options['form_select'] ) ) {
721 - continue;
722 - }
723 -
724 - if ( $type == 'all' ) {
725 - $sub_fields = self::get_all_for_form( $field->field_options['form_select'] );
726 - } else {
727 - $sub_fields = self::get_all_types_in_form( $field->field_options['form_select'], $type );
728 - }
729 -
730 - if ( ! empty( $sub_fields ) ) {
731 - $index = $k + $index_offset;
732 - $index_offset += count( $sub_fields );
733 - array_splice( $results, $index, 0, $sub_fields );
734 - }
735 - unset( $field, $sub_fields );
736 - }
737 - }
738 -
739 - public static function getAll( $where = array(), $order_by = '', $limit = '', $blog_id = false ) {
740 - $cache_key = FrmAppHelper::maybe_json_encode( $where ) . $order_by . 'l' . $limit . 'b' . $blog_id;
741 - if ( self::$use_cache ) {
742 - // make sure old cache doesn't get saved as a transient
743 - $results = wp_cache_get( $cache_key, 'frm_field' );
744 - if ( false !== $results ) {
745 - return wp_unslash( $results );
746 - }
747 - }
748 -
749 - global $wpdb;
750 -
751 - if ( $blog_id && is_multisite() ) {
752 - global $wpmuBaseTablePrefix;
753 - if ( $wpmuBaseTablePrefix ) {
754 - $prefix = $wpmuBaseTablePrefix . $blog_id . '_';
755 - } else {
756 - $prefix = $wpdb->get_blog_prefix( $blog_id );
757 - }
758 -
759 - $table_name = $prefix . 'frm_fields';
760 - $form_table_name = $prefix . 'frm_forms';
761 - } else {
762 - $table_name = $wpdb->prefix . 'frm_fields';
763 - $form_table_name = $wpdb->prefix . 'frm_forms';
764 - }
765 -
766 - if ( ! empty( $order_by ) && strpos( $order_by, 'ORDER BY' ) === false ) {
767 - $order_by = ' ORDER BY ' . $order_by;
768 - }
769 -
770 - $limit = FrmDb::esc_limit( $limit );
771 -
772 - $query = "SELECT fi.*, fr.name as form_name FROM {$table_name} fi LEFT OUTER JOIN {$form_table_name} fr ON fi.form_id=fr.id";
773 - $query_type = ( $limit == ' LIMIT 1' || $limit == 1 ) ? 'row' : 'results';
774 -
775 - if ( is_array( $where ) ) {
776 - $args = array(
777 - 'order_by' => $order_by,
778 - 'limit' => $limit,
779 - );
780 - $results = FrmDb::get_var( $table_name . ' fi LEFT OUTER JOIN ' . $form_table_name . ' fr ON fi.form_id=fr.id', $where, 'fi.*, fr.name as form_name', $args, '', $query_type );
781 - } else {
782 - // if the query is not an array, then it has already been prepared
783 - $query .= FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
784 -
785 - $function_name = ( $query_type == 'row' ) ? 'get_row' : 'get_results';
786 - $results = $wpdb->$function_name( $query );
787 - }
788 - unset( $where );
789 -
790 - self::format_field_results( $results );
791 -
792 - FrmDb::set_cache( $cache_key, $results, 'frm_field' );
793 -
794 - return wp_unslash( $results );
795 - }
796 -
797 - /**
798 - * @since 2.0.8
799 - */
800 - private static function format_field_results( &$results ) {
801 - if ( is_array( $results ) ) {
802 - foreach ( $results as $r_key => $result ) {
803 - FrmDb::set_cache( $result->id, $result, 'frm_field' );
804 - FrmDb::set_cache( $result->field_key, $result, 'frm_field' );
805 -
806 - self::prepare_options( $result );
807 - $results[ $r_key ]->field_options = $result->field_options;
808 - $results[ $r_key ]->options = $result->options;
809 - $results[ $r_key ]->default_value = $result->default_value;
810 -
811 - unset( $r_key, $result );
812 - }
813 - } elseif ( $results ) {
814 - FrmDb::set_cache( $results->id, $results, 'frm_field' );
815 - FrmDb::set_cache( $results->field_key, $results, 'frm_field' );
816 -
817 - self::prepare_options( $results );
818 - }
819 - }
820 -
821 - /**
822 - * Unserialize all the serialized field data
823 - *
824 - * @since 2.0
825 - */
826 - private static function prepare_options( &$results ) {
827 - FrmAppHelper::unserialize_or_decode( $results->field_options );
828 - FrmAppHelper::unserialize_or_decode( $results->options );
829 -
830 - // Allow a single box to be checked for the default value.
831 - $before = $results->default_value;
832 - FrmAppHelper::unserialize_or_decode( $results->default_value );
833 - if ( $before === $results->default_value && ! is_array( $before ) && strpos( $before, '["' ) === 0 ) {
834 - $results->default_value = FrmAppHelper::maybe_json_decode( $results->default_value );
835 - }
836 - }
837 -
838 - /**
839 - * If a form has too many fields, thay won't all save into a single transient.
840 - * We'll break them into groups of 200
841 - *
842 - * @since 2.0.1
843 - */
844 - private static function get_fields_from_transients( $form_id, $args ) {
845 - $fields = array();
846 - self::get_next_transient( $fields, 'frm_form_fields_' . $form_id . $args['inc_embed'] . $args['inc_repeat'] );
847 -
848 - return $fields;
849 - }
850 -
851 - /**
852 - * Called by get_fields_from_transients
853 - *
854 - * @since 2.0.1
855 - */
856 - private static function get_next_transient( &$fields, $base_name, $next = 0 ) {
857 - $name = $next ? $base_name . $next : $base_name;
858 - $next_fields = get_transient( $name );
859 -
860 - if ( $next_fields ) {
861 - $fields = array_merge( $fields, $next_fields );
862 -
863 - if ( count( $next_fields ) >= self::$transient_size ) {
864 - // if this transient is full, check for another
865 - $next ++;
866 - self::get_next_transient( $fields, $base_name, $next );
867 - }
868 - }
869 - }
870 -
871 - /**
872 - * Save the transients in chunks for large forms
873 - *
874 - * @since 2.0.1
875 - */
876 - private static function set_field_transient( &$fields, $form_id, $next = 0, $args = array() ) {
877 - $base_name = 'frm_form_fields_' . $form_id . $args['inc_embed'] . $args['inc_repeat'];
878 - $field_chunks = array_chunk( $fields, self::$transient_size );
879 -
880 - foreach ( $field_chunks as $field ) {
881 - $name = $next ? $base_name . $next : $base_name;
882 - $set = set_transient( $name, $field, 60 * 60 * 6 );
883 - if ( ! $set ) {
884 - // the transient didn't save
885 - if ( $name != $base_name ) {
886 - // if the first saved an others fail, this will show an incmoplete form
887 - self::delete_form_transient( $form_id );
888 - }
889 -
890 - return;
891 - }
892 -
893 - $next ++;
894 - }
895 - }
896 -
897 - public static function is_no_save_field( $type ) {
898 - return in_array( $type, self::no_save_fields() );
899 - }
900 -
901 - public static function no_save_fields() {
902 - return array( 'divider', 'end_divider', 'captcha', 'break', 'html', 'form', 'summary' );
903 - }
904 -
905 - /**
906 - * Check if this field can hold an array of values
907 - *
908 - * @since 2.0.9
909 - *
910 - * @param array|object $field
911 - *
912 - * @return boolean
913 - */
914 - public static function is_field_with_multiple_values( $field ) {
915 - if ( ! $field ) {
916 - return false;
917 - }
918 -
919 - $field_type = self::get_original_field_type( $field );
920 -
921 - $is_multi_value_field = (
922 - self::is_checkbox( $field ) ||
923 - $field_type == 'address' ||
924 - self::is_multiple_select( $field )
925 - );
926 -
927 - return $is_multi_value_field;
928 - }
929 -
930 - /**
931 - * @since 3.0
932 - * @return string
933 - */
934 - public static function get_field_type( $field ) {
935 - return is_array( $field ) ? $field['type'] : $field->type;
936 - }
937 -
938 - /**
939 - * @since 3.0
940 - * @return string
941 - */
942 - public static function get_original_field_type( $field ) {
943 - $field_type = self::get_field_type( $field );
944 - $original_type = self::get_option( $field, 'original_type' );
945 -
946 - if ( ! empty( $original_type ) && $original_type != $field_type ) {
947 - $field_type = $original_type; // check the original type for arrays
948 - }
949 -
950 - return $field_type;
951 - }
952 -
953 - /**
954 - * Check if this is a multiselect dropdown field
955 - *
956 - * @since 2.0.9
957 - * @return boolean
958 - */
959 - public static function is_multiple_select( $field ) {
960 - $field_type = self::get_field_type( $field );
961 - $is_multiple = self::is_option_true( $field, 'multiple' ) && self::is_field_type( $field, 'select' ) && $field_type !== 'hidden';
962 -
963 - return apply_filters( 'frm_is_multiple_select', $is_multiple, $field );
964 - }
965 -
966 - /**
967 - * Check if a field is read only. Read only can be set in the field options,
968 - * but disabled with the shortcode options
969 - *
970 - * @since 2.0.9
971 - */
972 - public static function is_read_only( $field ) {
973 - global $frm_vars;
974 -
975 - return ( self::is_option_true( $field, 'read_only' ) && ( ! isset( $frm_vars['readonly'] ) || $frm_vars['readonly'] != 'disabled' ) );
976 - }
977 -
978 - /**
979 - * @since 2.0.9
980 - */
981 - public static function is_required( $field ) {
982 - $required = ( $field['required'] != '0' );
983 - $required = apply_filters( 'frm_is_field_required', $required, $field );
984 -
985 - return $required;
986 - }
987 -
988 - /**
989 - * @since 2.0.9
990 - */
991 - public static function is_option_true( $field, $option ) {
992 - if ( is_array( $field ) ) {
993 - return self::is_option_true_in_array( $field, $option );
994 - } else {
995 - return self::is_option_true_in_object( $field, $option );
996 - }
997 - }
998 -
999 - /**
1000 - * @since 2.0.9
1001 - */
1002 - public static function is_option_empty( $field, $option ) {
1003 - if ( is_array( $field ) ) {
1004 - return self::is_option_empty_in_array( $field, $option );
1005 - } else {
1006 - return self::is_option_empty_in_object( $field, $option );
1007 - }
1008 - }
1009 -
1010 - public static function is_option_true_in_array( $field, $option ) {
1011 - return isset( $field[ $option ] ) && $field[ $option ];
1012 - }
1013 -
1014 - public static function is_option_true_in_object( $field, $option ) {
1015 - return isset( $field->field_options[ $option ] ) && $field->field_options[ $option ];
1016 - }
1017 -
1018 - public static function is_option_empty_in_array( $field, $option ) {
1019 - return ! isset( $field[ $option ] ) || empty( $field[ $option ] );
1020 - }
1021 -
1022 - public static function is_option_empty_in_object( $field, $option ) {
1023 - return ! isset( $field->field_options[ $option ] ) || empty( $field->field_options[ $option ] );
1024 - }
1025 -
1026 - public static function is_option_value_in_object( $field, $option ) {
1027 - return isset( $field->field_options[ $option ] ) && $field->field_options[ $option ] != '';
1028 - }
1029 -
1030 - /**
1031 - * @since 2.0.18
1032 - */
1033 - public static function get_option( $field, $option ) {
1034 - if ( is_array( $field ) ) {
1035 - $option = self::get_option_in_array( $field, $option );
1036 - } else {
1037 - $option = self::get_option_in_object( $field, $option );
1038 - }
1039 -
1040 - return $option;
1041 - }
1042 -
1043 - public static function get_option_in_array( $field, $option ) {
1044 -
1045 - if ( isset( $field[ $option ] ) ) {
1046 - $this_option = $field[ $option ];
1047 - } elseif ( isset( $field['field_options'] ) && is_array( $field['field_options'] ) && isset( $field['field_options'][ $option ] ) ) {
1048 - $this_option = $field['field_options'][ $option ];
1049 - } else {
1050 - $this_option = '';
1051 - }
1052 -
1053 - return $this_option;
1054 - }
1055 -
1056 - public static function get_option_in_object( $field, $option ) {
1057 - return isset( $field->field_options[ $option ] ) ? $field->field_options[ $option ] : '';
1058 - }
1059 -
1060 - /**
1061 - * @since 2.0.09
1062 - */
1063 - public static function is_repeating_field( $field ) {
1064 - if ( is_array( $field ) ) {
1065 - $is_repeating_field = ( 'divider' == $field['type'] );
1066 - } else {
1067 - $is_repeating_field = ( 'divider' == $field->type );
1068 - }
1069 -
1070 - return ( $is_repeating_field && self::is_option_true( $field, 'repeat' ) );
1071 - }
1072 -
1073 - /**
1074 - * @param string $key
1075 - *
1076 - * @return int field id
1077 - */
1078 - public static function get_id_by_key( $key ) {
1079 - $id = FrmDb::get_var( 'frm_fields', array( 'field_key' => sanitize_title( $key ) ) );
1080 -
1081 - return (int) $id;
1082 - }
1083 -
1084 - /**
1085 - * @param string $id
1086 - *
1087 - * @return null|string
1088 - */
1089 - public static function get_key_by_id( $id ) {
1090 - return FrmDb::get_var( 'frm_fields', array( 'id' => $id ), 'field_key' );
1091 - }
1092 -
1093 - public static function is_image( $field ) {
1094 - $type = self::get_field_type( $field );
1095 -
1096 - return ( $type == 'url' && self::get_option( $field, 'show_image' ) );
1097 - }
1098 -
1099 - /**
1100 - * Check if field is radio or Dynamic radio
1101 - *
1102 - * @since 3.0
1103 - *
1104 - * @param array|object $field
1105 - *
1106 - * @return boolean true if field type is radio or Dynamic radio
1107 - */
1108 - public static function is_radio( $field ) {
1109 - return self::is_field_type( $field, 'radio' );
1110 - }
1111 -
1112 - /**
1113 - * Check if field is checkbox or Dynamic checkbox
1114 - *
1115 - * @since 3.0
1116 - *
1117 - * @param array|object $field
1118 - *
1119 - * @return boolean true if field type is checkbox or Dynamic checkbox
1120 - */
1121 - public static function is_checkbox( $field ) {
1122 - return self::is_field_type( $field, 'checkbox' );
1123 - }
1124 -
1125 - /**
1126 - * Check if field is checkbox or radio
1127 - *
1128 - * @since 3.0
1129 - *
1130 - * @param array|object $field
1131 - * @param string $is_type Options include radio, checkbox, text
1132 - *
1133 - * @return boolean true if field type is checkbox or Dynamic checkbox
1134 - */
1135 - public static function is_field_type( $field, $is_type ) {
1136 - $field_type = self::get_original_field_type( $field );
1137 - $data_type = self::get_option( $field, 'data_type' );
1138 -
1139 - $is_field_type = (
1140 - $is_type === $field_type ||
1141 - ( 'data' === $field_type && $is_type === $data_type ) ||
1142 - ( 'lookup' === $field_type && $is_type === $data_type ) ||
1143 - ( 'product' === $field_type && $is_type === $data_type )
1144 - );
1145 -
1146 - /**
1147 - * When a field type is checked, allow individual fields
1148 - * to set the type.
1149 - *
1150 - * @since 4.04
1151 - */
1152 - return apply_filters( 'frm_is_field_type', $is_field_type, compact( 'field', 'is_type' ) );
1153 - }
1154 -
1155 - /**
1156 - * Checks if the given field array is a combo field.
1157 - *
1158 - * @since 4.10.02
1159 - *
1160 - * @param array $field Field array.
1161 - * @return bool
1162 - */
1163 - public static function is_combo_field( $field ) {
1164 - $field_type_obj = FrmFieldFactory::get_field_factory( $field );
1165 -
1166 - return ! empty( $field_type_obj->is_combo_field );
1167 - }
241 + function getIds($where = '', $order_by = '', $limit = ''){
242 + global $wpdb;
243 +
244 + if ( !empty($order_by) && !preg_match("/ORDER BY/", $order_by) ){
245 + $order_by = ' ORDER BY '. $order_by;
246 + }
247 +
248 + $query = "SELECT fi.id FROM {$wpdb->prefix}frm_fields fi " .
249 + "LEFT OUTER JOIN {$wpdb->prefix}frm_forms fr ON fi.form_id=fr.id" .
250 + FrmAppHelper::prepend_and_or_where(' WHERE ', $where) . $order_by . $limit;
251 + if ($limit == ' LIMIT 1' or $limit == 1)
252 + $results = $wpdb->get_var($query);
253 + else
254 + $results = $wpdb->get_col($query);
255 + return $results;
256 + }
1168 257 }