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/FrmDb.php +297 -799 6.35 → 1.07.11 View file →
@@ -1,830 +1,328 @@
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 FrmDb {
4 +if(class_exists('FrmDb'))
5 + return;
7 6
8 - /**
9 - * Change array into format $wpdb->prepare can use
10 - *
11 - * @param array $args
12 - * @param string $starts_with
13 - *
14 - * @return void
15 - */
16 - public static function get_where_clause_and_values( &$args, $starts_with = ' WHERE ' ) {
17 - if ( ! $args ) {
18 - // Add an arg to prevent prepare from failing
19 - $args = array(
20 - 'where' => $starts_with . '1=%d',
21 - 'values' => array( 1 ),
22 - );
7 +class FrmDb{
8 +
9 + function __construct(){
10 + global $wpdb;
11 + $this->fields = $wpdb->prefix . "frm_fields";
12 + $this->forms = $wpdb->prefix . "frm_forms";
13 + $this->entries = $wpdb->prefix . "frm_items";
14 + $this->entry_metas = $wpdb->prefix . "frm_item_metas";
15 + }
16 +
17 + function upgrade($old_db_version=false){
18 + global $wpdb;
19 + //$frm_db_version is the version of the database we're moving to
20 + $frm_db_version = FrmAppHelper::$db_version;
21 + $old_db_version = (float)$old_db_version;
22 + if(!$old_db_version)
23 + $old_db_version = get_option('frm_db_version');
23 24
24 - return;
25 - }
25 + if ($frm_db_version != $old_db_version){
26 + require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
27 +
28 + $charset_collate = '';
29 + if( $wpdb->has_cap( 'collation' ) ){
30 + if( !empty($wpdb->charset) )
31 + $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
32 + if( !empty($wpdb->collate) )
33 + $charset_collate .= " COLLATE $wpdb->collate";
34 + }
26 35
27 - $where = '';
28 - $values = array();
36 + /* Create/Upgrade Fields Table */
37 + $sql = "CREATE TABLE {$this->fields} (
38 + id int(11) NOT NULL auto_increment,
39 + field_key varchar(255) default NULL,
40 + name text default NULL,
41 + description text default NULL,
42 + type text default NULL,
43 + default_value longtext default NULL,
44 + options longtext default NULL,
45 + field_order int(11) default 0,
46 + required int(1) default NULL,
47 + field_options longtext default NULL,
48 + form_id int(11) default NULL,
49 + created_at datetime NOT NULL,
50 + PRIMARY KEY (id),
51 + KEY form_id (form_id),
52 + UNIQUE KEY field_key (field_key)
53 + ) {$charset_collate};";
29 54
30 - if ( is_array( $args ) ) {
31 - $base_where = $starts_with;
32 - self::parse_where_from_array( $args, $base_where, $where, $values );
33 - }
55 + dbDelta($sql);
56 +
57 + /* Create/Upgrade Forms Table */
58 + $sql = "CREATE TABLE {$this->forms} (
59 + id int(11) NOT NULL auto_increment,
60 + form_key varchar(255) default NULL,
61 + name varchar(255) default NULL,
62 + description text default NULL,
63 + parent_form_id int(11) default NULL,
64 + logged_in tinyint(1) default NULL,
65 + editable tinyint(1) default NULL,
66 + is_template tinyint(1) default 0,
67 + default_template tinyint(1) default 0,
68 + status varchar(255) default NULL,
69 + prli_link_id int(11) default NULL,
70 + options longtext default NULL,
71 + created_at datetime NOT NULL,
72 + PRIMARY KEY (id),
73 + UNIQUE KEY form_key (form_key)
74 + ) {$charset_collate};";
34 75
35 - $args = compact( 'where', 'values' );
36 - }
76 + dbDelta($sql);
37 77
38 - /**
39 - * @param array $args
40 - * @param string $base_where
41 - * @param string $where
42 - * @param array $values
43 - *
44 - * @return void
45 - */
46 - public static function parse_where_from_array( $args, $base_where, &$where, &$values ) {
47 - $condition = ' AND';
78 + /* Create/Upgrade Items Table */
79 + $sql = "CREATE TABLE {$this->entries} (
80 + id int(11) NOT NULL auto_increment,
81 + item_key varchar(255) default NULL,
82 + name varchar(255) default NULL,
83 + description text default NULL,
84 + ip text default NULL,
85 + form_id int(11) default NULL,
86 + post_id int(11) default NULL,
87 + user_id int(11) default NULL,
88 + parent_item_id int(11) default NULL,
89 + is_draft tinyint(1) default 0,
90 + updated_by int(11) default NULL,
91 + created_at datetime NOT NULL,
92 + updated_at datetime NOT NULL,
93 + PRIMARY KEY (id),
94 + KEY form_id (form_id),
95 + KEY post_id (post_id),
96 + KEY user_id (user_id),
97 + KEY parent_item_id (parent_item_id),
98 + UNIQUE KEY item_key (item_key)
99 + ) {$charset_collate};";
48 100
49 - if ( isset( $args['or'] ) ) {
50 - $condition = ' OR';
51 - unset( $args['or'] );
52 - }
101 + dbDelta($sql);
53 102
54 - foreach ( $args as $key => $value ) {
55 - $where .= $where ? $condition : $base_where;
56 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
57 - $array_inc_null = ! is_numeric( $key ) && is_array( $value ) && in_array( null, $value );
103 + /* Create/Upgrade Meta Table */
104 + $sql = "CREATE TABLE {$this->entry_metas} (
105 + id int(11) NOT NULL auto_increment,
106 + meta_value longtext default NULL,
107 + field_id int(11) NOT NULL,
108 + item_id int(11) NOT NULL,
109 + created_at datetime NOT NULL,
110 + PRIMARY KEY (id),
111 + KEY field_id (field_id),
112 + KEY item_id (item_id)
113 + ) {$charset_collate};";
58 114
59 - if ( is_numeric( $key ) || $array_inc_null ) {
60 - $where .= ' ( ';
61 - $nested_where = '';
115 + dbDelta($sql);
116 +
117 + /**** MIGRATE DATA ****/
118 + if ($frm_db_version >= 1.03 and $old_db_version < 1.03){
119 + global $frm_entry;
120 + $all_entries = $frm_entry->getAll();
121 + foreach($all_entries as $ent){
122 + $opts = maybe_unserialize($ent->description);
123 + if(is_array($opts) and in_array($opts['ip']))
124 + $wpdb->update( $this->entries, array('ip' => $opts['ip']), array( 'id' => $ent->id ) );
125 + }
126 + }
127 +
128 + if($frm_db_version >= 4 and $old_db_version < 4){
129 + global $frm_entry_meta;
130 + $user_ids = $frm_entry_meta->getAll("fi.type='user_id'");
131 + foreach($user_ids as $user_id)
132 + $wpdb->update( $this->entries, array('user_id' => $user_id->meta_value), array('id' => $user_id->item_id) );
133 + }
134 +
135 + if($frm_db_version >= 6 and $old_db_version < 6){
136 + $fields = $wpdb->get_results("SELECT id, field_options FROM $this->fields WHERE type not in ('hidden', 'user_id', 'break', 'divider', 'html', 'captcha', 'form')");
137 + $default_html = <<<DEFAULT_HTML
138 +<div id="frm_field_[id]_container" class="form-field [required_class] [error_class]">
139 + <label class="frm_pos_[label_position]">[field_name]
140 + <span class="frm_required">[required_label]</span>
141 + </label>
142 + [input]
143 + [if description]<div class="frm_description">[description]</div>[/if description]
144 +</div>
145 +DEFAULT_HTML;
146 + $old_default_html = <<<DEFAULT_HTML
147 +<div id="frm_field_[id]_container" class="form-field [required_class] [error_class]">
148 + <label class="frm_pos_[label_position]">[field_name]
149 + <span class="frm_required">[required_label]</span>
150 + </label>
151 + [input]
152 + [if description]<p class="frm_description">[description]</p>[/if description]
153 +</div>
154 +DEFAULT_HTML;
155 + $new_default_html = FrmFieldsHelper::get_default_html('text');
156 + foreach($fields as $field){
157 + $field->field_options = maybe_unserialize($field->field_options);
158 + if ( !isset($field->field_options['custom_html']) || empty($field->field_options['custom_html']) || $field->field_options['custom_html'] == $default_html || $field->field_options['custom_html'] == $old_default_html ) {
159 + $field->field_options['custom_html'] = $new_default_html;
160 + $wpdb->update($this->fields, array('field_options' => maybe_serialize($field->field_options)), array( 'id' => $field->id ));
161 + }
162 + unset($field);
163 + }
164 + unset($default_html);
165 + unset($old_default_html);
166 + unset($fields);
167 + }
168 +
169 + if($frm_db_version >= 11 and $old_db_version < 11){
170 + $forms = $wpdb->get_results("SELECT id, options FROM $this->forms");
171 + $sending = __('Sending', 'formidable');
172 + $img = FrmAppHelper::plugin_url() .'/images/ajax_loader.gif';
173 + $old_default_html = <<<DEFAULT_HTML
174 +<div class="frm_submit">
175 +[if back_button]<input type="submit" value="[back_label]" name="frm_prev_page" formnovalidate="formnovalidate" [back_hook] />[/if back_button]
176 +<input type="submit" value="[button_label]" [button_action] />
177 +<img class="frm_ajax_loading" src="$img" alt="$sending" style="visibility:hidden;" />
178 +</div>
179 +DEFAULT_HTML;
180 + unset($sending);
181 + unset($img);
182 +
183 + $new_default_html = FrmFormsHelper::get_default_html('submit');
184 + $draft_link = FrmFormsHelper::get_draft_link();
185 + foreach($forms as $form){
186 + $form->options = maybe_unserialize($form->options);
187 + if(!isset($form->options['submit_html']) or empty($form->options['submit_html']))
188 + continue;
189 +
190 + if ( $form->options['submit_html'] != $new_default_html && $form->options['submit_html'] == $old_default_html ) {
191 + $form->options['submit_html'] = $new_default_html;
192 + $wpdb->update($this->forms, array('options' => serialize($form->options)), array( 'id' => $form->id ));
193 + }else if(!strpos($form->options['submit_html'], 'save_draft')){
194 + $form->options['submit_html'] = preg_replace('~\<\/div\>(?!.*\<\/div\>)~', $draft_link ."\r\n</div>", $form->options['submit_html']);
195 + $wpdb->update($this->forms, array('options' => serialize($form->options)), array( 'id' => $form->id ));
196 + }
197 + unset($form);
198 + }
199 + unset($forms);
200 + }
201 +
202 +
62 203
63 - if ( $array_inc_null ) {
64 - foreach ( $value as $val ) {
65 - $parse_where = array(
66 - $key => $val,
67 - 'or' => 1,
68 - );
69 - self::parse_where_from_array( $parse_where, '', $nested_where, $values );
70 - }
71 - } else {
72 - self::parse_where_from_array( $value, '', $nested_where, $values );
73 - }
204 + /**** ADD/UPDATE DEFAULT TEMPLATES ****/
205 + if ( class_exists('FrmXMLController') ) {
206 + FrmXMLController::add_default_templates();
207 + }
74 208
75 - $where .= $nested_where;
76 - $where .= ' ) ';
77 - } else {
78 - self::interpret_array_to_sql( $key, $value, $where, $values );
79 - }//end if
80 - }//end foreach
81 - }
209 +
210 + /***** SAVE DB VERSION *****/
211 + update_option('frm_db_version', $frm_db_version);
212 + }
82 213
83 - /**
84 - * @param string $key
85 - * @param array|string|null $value
86 - * @param string $where
87 - * @param array $values
88 - *
89 - * @return void
90 - */
91 - private static function interpret_array_to_sql( $key, $value, &$where, &$values ) {
92 - $key = trim( $key );
214 + do_action('frm_after_install');
215 + }
216 +
217 + function get_count($table, $args=array()){
218 + global $wpdb;
219 + extract(FrmDb::get_where_clause_and_values( $args ));
93 220
94 - if ( str_contains( $key, 'created_at' ) || str_contains( $key, 'updated_at' ) ) {
95 - $k = explode( ' ', $key );
96 - $where .= ' CAST(' . reset( $k ) . ' as CHAR) ' . str_replace( reset( $k ), '', $key );
97 - } else {
98 - $where .= ' ' . $key;
99 - }
221 + $query = "SELECT COUNT(*) FROM {$table}{$where}";
222 + $query = $wpdb->prepare($query, $values);
223 + return $wpdb->get_var($query);
224 + }
100 225
101 - $lowercase_key = explode( ' ', strtolower( $key ) );
102 - $lowercase_key = end( $lowercase_key );
226 + function get_where_clause_and_values( $args ){
227 + $where = '';
228 + $values = array();
229 + if(is_array($args)){
230 + foreach($args as $key => $value){
231 + $where .= (!empty($where)) ? ' AND' : ' WHERE';
232 + $where .= " {$key}=";
233 + $where .= is_numeric($value) ? (strpos($value, ".") !== false ? '%f' : '%d') : '%s';
234 +
235 + $values[] = $value;
236 + }
237 + }
103 238
104 - if ( is_array( $value ) ) {
105 - // Translate array of values to "in"
106 - if ( str_contains( $lowercase_key, 'like' ) ) {
107 - $where = preg_replace( '/' . $key . '$/', '', $where );
108 - $where .= '(';
109 - $start = true;
239 + return compact('where', 'values');
240 + }
241 +
242 + function get_var($table, $args=array(), $field='id', $order_by=''){
243 + global $wpdb;
110 244
111 - foreach ( $value as $v ) {
112 - if ( ! $start ) {
113 - $where .= ' OR ';
114 - }
245 + extract(FrmDb::get_where_clause_and_values( $args ));
246 + if(!empty($order_by))
247 + $order_by = " ORDER BY {$order_by}";
115 248
116 - $start = false;
117 - $where .= $key . ' %s';
118 - $values[] = '%' . self::esc_like( $v ) . '%';
119 - }
249 + $query = $wpdb->prepare("SELECT {$field} FROM {$table}{$where}{$order_by} LIMIT 1", $values);
250 + return $wpdb->get_var($query);
251 + }
252 +
253 + function get_col($table, $args=array(), $field='id', $order_by=''){
254 + global $wpdb;
120 255
121 - $where .= ')';
122 - } elseif ( $value ) {
123 - $where .= ' in (' . self::prepare_array_values( $value, '%s' ) . ')';
124 - $values = array_merge( $values, $value );
125 - }
126 - } elseif ( str_contains( $lowercase_key, 'like' ) ) {
127 - /**
128 - * Allow string to start or end with the value
129 - * If the key is like% then skip the first % for starts with
130 - * If the key is %like then skip the last % for ends with
131 - */
132 - $start = '%';
133 - $end = '%';
256 + extract(FrmDb::get_where_clause_and_values( $args ));
257 + if(!empty($order_by))
258 + $order_by = " ORDER BY {$order_by}";
134 259
135 - if ( $lowercase_key === 'like%' ) {
136 - $start = '';
137 - $where = rtrim( $where, '%' );
138 - } elseif ( $lowercase_key === '%like' ) {
139 - $end = '';
140 - $where = rtrim( rtrim( $where, '%like' ), '%LIKE' );
141 - $where .= 'like';
142 - }
260 + $query = $wpdb->prepare("SELECT {$field} FROM {$table}{$where}{$order_by}", $values);
261 + return $wpdb->get_col($query);
262 + }
143 263
144 - $where .= ' %s';
145 - $values[] = $start . self::esc_like( $value ) . $end;
146 - } elseif ( $value === null ) {
147 - $where .= ' IS NULL';
148 - } else {
149 - // allow a - to prevent = from being added
150 - if ( str_ends_with( $key, '-' ) ) {
151 - $where = rtrim( $where, '-' );
152 - } else {
153 - $where .= '=';
154 - }
264 + function get_one_record($table, $args=array(), $fields='*', $order_by=''){
265 + global $wpdb;
155 266
156 - self::add_query_placeholder( $key, $value, $where );
267 + extract(FrmDb::get_where_clause_and_values( $args ));
268 +
269 + if(!empty($order_by))
270 + $order_by = " ORDER BY {$order_by}";
157 271
158 - $values[] = $value;
159 - }//end if
160 - }
272 + $query = "SELECT {$fields} FROM {$table}{$where} {$order_by} LIMIT 1";
273 + $query = $wpdb->prepare($query, $values);
274 + return $wpdb->get_row($query);
275 + }
161 276
162 - /**
163 - * Add %d, or %s to query
164 - *
165 - * @since 2.02.05
166 - *
167 - * @param string $key
168 - * @param int|string $value
169 - * @param string $where
170 - *
171 - * @return void
172 - */
173 - private static function add_query_placeholder( $key, $value, &$where ) {
174 - if ( is_numeric( $value ) && ( ! str_contains( $key, 'meta_value' ) || str_contains( $key, '+0' ) ) ) {
175 - // Switch string to number.
176 - $value = $value + 0;
177 - $where .= is_float( $value ) ? '%f' : '%d';
178 - } else {
179 - $where .= '%s';
180 - }
181 - }
277 + function get_records($table, $args=array(), $order_by='', $limit='', $fields='*'){
278 + global $wpdb;
182 279
183 - /**
184 - * @param string $table
185 - * @param array $where
186 - * @param array $args
187 - *
188 - * @return int
189 - */
190 - public static function get_count( $table, $where = array(), $args = array() ) {
191 - $count = self::get_var( $table, $where, 'COUNT(*)', $args );
192 - return (int) $count;
193 - }
280 + extract(FrmDb::get_where_clause_and_values( $args ));
194 281
195 - /**
196 - * @param string $table
197 - * @param array $where
198 - * @param string $field
199 - * @param array $args
200 - * @param string $limit
201 - * @param string $type
202 - *
203 - * @return array|object|string|null
204 - */
205 - public static function get_var( $table, $where = array(), $field = 'id', $args = array(), $limit = '', $type = 'var' ) {
206 - $group = '';
207 - self::get_group_and_table_name( $table, $group );
208 - self::convert_options_to_array( $args, '', $limit );
282 + if ( !empty($order_by) && strpos($order_by, ' ORDER BY ') === false ) {
283 + $order_by = " ORDER BY {$order_by}";
284 + }
209 285
210 - if ( $type === 'var' && ! isset( $args['limit'] ) ) {
211 - $args['limit'] = 1;
212 - }
286 + if ( !empty($limit) && strpos($order_by, ' LIMIT ') === false ) {
287 + $limit = " LIMIT {$limit}";
288 + }
213 289
214 - $query = self::generate_query_string_from_pieces( $field, $table, $where, $args );
215 - $cache_key = self::generate_cache_key( $where, $args, $field, $type );
216 -
217 - return self::check_cache( $cache_key, $group, $query, 'get_' . $type );
218 - }
219 -
220 - /**
221 - * Generate a cache key from the where query, field, type, and other arguments
222 - *
223 - * @since 2.03.07
224 - *
225 - * @param array $where
226 - * @param array $args
227 - * @param string $field
228 - * @param string $type
229 - *
230 - * @return string
231 - */
232 - public static function generate_cache_key( $where, $args, $field, $type ) {
233 - $cache_key = '';
234 - $where = FrmAppHelper::array_flatten( $where );
235 -
236 - foreach ( $where as $key => $value ) {
237 - $cache_key .= $key . '_' . $value;
290 + $query = "SELECT {$fields} FROM {$table}{$where}{$order_by}{$limit}";
291 + $query = $wpdb->prepare($query, $values);
292 + return $wpdb->get_results($query);
293 + }
294 +
295 + function uninstall(){
296 + if ( !current_user_can('administrator') ) {
297 + global $frm_settings;
298 + wp_die($frm_settings->admin_permission);
299 + }
300 +
301 + global $wpdb, $wp_roles;
302 +
303 + $wpdb->query('DROP TABLE IF EXISTS '. $this->fields);
304 + $wpdb->query('DROP TABLE IF EXISTS '. $this->forms);
305 + $wpdb->query('DROP TABLE IF EXISTS '. $this->entries);
306 + $wpdb->query('DROP TABLE IF EXISTS '. $this->entry_metas);
307 +
308 + delete_option('frm_options');
309 + delete_option('frm_db_version');
310 +
311 + //delete roles
312 + $frm_roles = FrmAppHelper::frm_capabilities();
313 + $roles = get_editable_roles();
314 + foreach($frm_roles as $frm_role => $frm_role_description){
315 + foreach ($roles as $role => $details){
316 + $wp_roles->remove_cap( $role, $frm_role );
317 + unset($role);
318 + unset($details);
319 + }
320 + unset($frm_role);
321 + unset($frm_role_description);
238 322 }
239 -
240 - $cache_key .= implode( '_', $args ) . $field . '_' . $type;
241 -
242 - return str_replace( array( ' ', ',' ), '_', $cache_key );
243 - }
244 -
245 - /**
246 - * @param string $table
247 - * @param array $where
248 - * @param string $field
249 - * @param array $args
250 - * @param string $limit
251 - *
252 - * @return array
253 - */
254 - public static function get_col( $table, $where = array(), $field = 'id', $args = array(), $limit = '' ) {
255 - return self::get_var( $table, $where, $field, $args, $limit, 'col' );
256 - }
257 -
258 - /**
259 - * @since 2.0
260 - *
261 - * @param string $table
262 - * @param array $where
263 - * @param string $fields
264 - * @param array $args
265 - *
266 - * @return mixed
267 - */
268 - public static function get_row( $table, $where = array(), $fields = '*', $args = array() ) {
269 - $args['limit'] = 1;
270 - return self::get_var( $table, $where, $fields, $args, '', 'row' );
271 - }
272 -
273 - /**
274 - * Prepare a key/value array before DB call
275 - *
276 - * @since 2.0
277 - *
278 - * @param string $table
279 - * @param array $where
280 - * @param string $fields
281 - * @param array $args
282 - *
283 - * @return array
284 - */
285 - public static function get_results( $table, $where = array(), $fields = '*', $args = array() ) {
286 - return self::get_var( $table, $where, $fields, $args, '', 'results' );
287 - }
288 -
289 - /**
290 - * Check for like, not like, in, not in, =, !=, >, <, <=, >=
291 - * Return a value to append to the where array key
292 - *
293 - * @param string $where_is
294 - *
295 - * @return string
296 - */
297 - public static function append_where_is( $where_is ) {
298 - $switch_to = array(
299 - '=' => '',
300 - '!=' => '!',
301 - '<=' => '<',
302 - '>=' => '>',
303 - 'like' => 'like',
304 - 'not like' => 'not like',
305 - 'in' => '',
306 - 'not in' => 'not',
307 - 'like%' => 'like%',
308 - '%like' => '%like',
309 - );
310 -
311 - $where_is = strtolower( $where_is );
312 -
313 - if ( isset( $switch_to[ $where_is ] ) ) {
314 - return ' ' . $switch_to[ $where_is ];
315 - }
316 -
317 - // > and < need a little more work since we don't want them switched to >= and <=
318 - if ( $where_is === '>' || $where_is === '<' ) {
319 - // The - indicates that the = should not be added later.
320 - return ' ' . $where_is . '-';
321 - }
322 -
323 - // fallback to = if the query is none of these
324 - return '';
325 - }
326 -
327 - /**
328 - * Get 'frm_forms' from wp_frm_forms or a longer table param that includes a join
329 - * Also add the wpdb->prefix to the table if it's missing
330 - *
331 - * @param string $table
332 - * @param string $group
333 - *
334 - * @return void
335 - */
336 - private static function get_group_and_table_name( &$table, &$group ) {
337 - global $wpdb;
338 -
339 - $table_parts = explode( ' ', $table );
340 - $group = reset( $table_parts );
341 - self::maybe_remove_prefix( $wpdb->prefix, $group );
342 -
343 - $prefix = $wpdb->base_prefix;
344 - self::maybe_remove_prefix( $prefix, $group );
345 -
346 - if ( $group === $table ) {
347 - $table = $wpdb->prefix . $table;
348 - }
349 -
350 - // Switch to singular group name
351 - $group = rtrim( $group, 's' );
352 - }
353 -
354 - /**
355 - * Only remove the db prefix when at the beginning.
356 - *
357 - * @since 4.04.02
358 - *
359 - * @param string $prefix Prefix to remove.
360 - * @param string $name Name to strip prefix from, passed by reference.
361 - *
362 - * @return void
363 - */
364 - private static function maybe_remove_prefix( $prefix, &$name ) {
365 - if ( str_starts_with( $name, $prefix ) ) {
366 - $name = substr( $name, strlen( $prefix ) );
367 - }
368 - }
369 -
370 - /**
371 - * @param array|string $args
372 - * @param string $order_by
373 - * @param int|string $limit
374 - *
375 - * @return void
376 - */
377 - private static function convert_options_to_array( &$args, $order_by = '', $limit = '' ) {
378 - if ( ! is_array( $args ) ) {
379 - $args = array( 'order_by' => $args );
380 - }
381 -
382 - if ( $order_by ) {
383 - $args['order_by'] = $order_by;
384 - }
385 -
386 - if ( $limit ) {
387 - $args['limit'] = $limit;
388 - }
389 -
390 - $temp_args = $args;
391 -
392 - foreach ( $temp_args as $k => $v ) {
393 - // phpcs:ignore Universal.Operators.StrictComparisons
394 - if ( $v == '' ) {
395 - unset( $args[ $k ] );
396 - continue;
397 - }
398 -
399 - $db_name = strtoupper( str_replace( '_', ' ', $k ) );
400 -
401 - if ( ! str_contains( $v, $db_name ) ) {
402 - $args[ $k ] = $db_name . ' ' . $v;
403 - }
404 - }
405 -
406 - // Make sure LIMIT is the last argument
407 - if ( ! isset( $args['order_by'] ) || ! isset( $args['limit'] ) ) {
408 - return;
409 - }
410 -
411 - $temp_limit = $args['limit'];
412 - unset( $args['limit'] );
413 - $args['limit'] = $temp_limit;
414 - }
415 -
416 - /**
417 - * Get the associative array results for the given columns, table, and where query
418 - *
419 - * @since 2.02.05
420 - *
421 - * @param string $columns
422 - * @param string $table
423 - * @param array $where
424 - *
425 - * @return mixed
426 - */
427 - public static function get_associative_array_results( $columns, $table, $where ) {
428 - $group = '';
429 - self::get_group_and_table_name( $table, $group );
430 -
431 - $query = self::generate_query_string_from_pieces( $columns, $table, $where );
432 - $cache_key = str_replace( array( ' ', ',' ), '_', trim( implode( '_', FrmAppHelper::array_flatten( $where ) ) . $columns . '_results_ARRAY_A', ' WHERE' ) );
433 -
434 - return self::check_cache( $cache_key, $group, $query, 'get_associative_results' );
435 - }
436 -
437 - /**
438 - * Combine the pieces of a query to form a full, prepared query
439 - *
440 - * @since 2.02.05
441 - *
442 - * @param string $columns
443 - * @param string $table
444 - * @param mixed $where
445 - * @param array $args
446 - *
447 - * @return string
448 - */
449 - private static function generate_query_string_from_pieces( $columns, $table, $where, $args = array() ) {
450 - $query = 'SELECT ' . $columns . ' FROM ' . $table;
451 -
452 - self::esc_query_args( $args );
453 -
454 - if ( ! is_array( $where ) && $where ) {
455 - return $query;
456 - }
457 -
458 - self::get_where_clause_and_values( $where );
459 - global $wpdb;
460 -
461 - // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
462 - return $wpdb->prepare( $query . $where['where'] . ' ' . implode( ' ', $args ), $where['values'] );
463 - }
464 -
465 - /**
466 - * @since 2.05.07
467 - *
468 - * @param array $args Query arguments, passed by reference.
469 - *
470 - * @return void
471 - */
472 - private static function esc_query_args( &$args ) {
473 - foreach ( $args as $param => $value ) {
474 - if ( $param === 'order_by' ) {
475 - $args[ $param ] = self::esc_order( $value );
476 - } elseif ( $param === 'limit' ) {
477 - $args[ $param ] = self::esc_limit( $value );
478 - }
479 -
480 - // phpcs:ignore Universal.Operators.StrictComparisons
481 - if ( $args[ $param ] == '' ) {
482 - unset( $args[ $param ] );
483 - }
484 - }
485 - }
486 -
487 - /**
488 - * Added for < WP 4.0 compatibility
489 - *
490 - * @since 2.05.06
491 - *
492 - * @param string $term The value to escape.
493 - *
494 - * @return string The escaped value
495 - */
496 - public static function esc_like( $term ) {
497 - global $wpdb;
498 - return $wpdb->esc_like( $term );
499 - }
500 -
501 - /**
502 - * @since 2.05.06
503 - *
504 - * @param string $order_query
505 - *
506 - * @return string
507 - */
508 - public static function esc_order( $order_query ) {
509 - if ( ! $order_query ) {
510 - return '';
511 - }
512 -
513 - // Remove ORDER BY before sanitizing.
514 - $order_query = strtolower( $order_query );
515 -
516 - if ( str_contains( $order_query, 'order by' ) ) {
517 - $order_query = str_replace( 'order by', '', $order_query );
518 - }
519 -
520 - $order_query = explode( ' ', trim( $order_query ) );
521 - $order = trim( reset( $order_query ) );
522 - $safe_order = array( 'count(*)' );
523 -
524 - if ( ! in_array( strtolower( $order ), $safe_order, true ) ) {
525 - $order = preg_replace( '/[^a-zA-Z0-9\-\_\.\+]/', '', $order );
526 - }
527 -
528 - $order_by = '';
529 -
530 - if ( count( $order_query ) > 1 ) {
531 - $order_by = end( $order_query );
532 - self::esc_order_by( $order_by );
533 - }
534 -
535 - return ' ORDER BY ' . $order . ' ' . $order_by;
536 - }
537 -
538 - /**
539 - * Make sure this is ordering by either ASC or DESC
540 - *
541 - * @since 2.05.06
542 - *
543 - * @param string $order_by Sort direction, passed by reference.
544 - *
545 - * @return void
546 - */
547 - public static function esc_order_by( &$order_by ) {
548 - $sort_options = array( 'asc', 'desc' );
549 -
550 - if ( ! in_array( strtolower( $order_by ), $sort_options, true ) ) {
551 - $order_by = 'asc';
552 - }
553 - }
554 -
555 - /**
556 - * @since 2.05.06
557 - *
558 - * @param string $limit
559 - *
560 - * @return string
561 - */
562 - public static function esc_limit( $limit ) {
563 - if ( ! $limit ) {
564 - return '';
565 - }
566 -
567 - $limit = trim( str_replace( 'limit ', '', strtolower( $limit ) ) );
568 -
569 - if ( is_numeric( $limit ) ) {
570 - return ' LIMIT ' . $limit;
571 - }
572 -
573 - $limit = explode( ',', trim( $limit ) );
574 -
575 - foreach ( $limit as $k => $l ) {
576 - if ( is_numeric( $l ) ) {
577 - $limit[ $k ] = $l;
578 - }
579 - }
580 -
581 - $limit = implode( ',', $limit );
582 -
583 - return ' LIMIT ' . $limit;
584 - }
585 -
586 - /**
587 - * Get an array of values ready to go through $wpdb->prepare
588 - *
589 - * @since 2.05.06
590 - *
591 - * @param array $array Array of values.
592 - * @param string $type Placeholder type.
593 - *
594 - * @return string
595 - */
596 - public static function prepare_array_values( $array, $type = '%s' ) {
597 - $placeholders = array_fill( 0, count( $array ), $type );
598 - return implode( ', ', $placeholders );
599 - }
600 -
601 - /**
602 - * @since 2.05.06
603 - *
604 - * @param string $starts_with
605 - * @param array|string $where
606 - *
607 - * @return string
608 - */
609 - public static function prepend_and_or_where( $starts_with = ' WHERE ', $where = '' ) {
610 - if ( ! $where ) {
611 - $where = '';
612 - } elseif ( is_array( $where ) ) {
613 - global $wpdb;
614 - self::get_where_clause_and_values( $where, $starts_with );
615 - $where = $wpdb->prepare( $where['where'], $where['values'] ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
616 - } else {
617 - $where = $starts_with . $where;
618 - }
619 -
620 - /**
621 - * Allows modifying where clause when using FrmDb::prepend_and_or_where() method.
622 - *
623 - * @since 5.0.16
624 - *
625 - * @param string $where Where string.
626 - * @param string $starts_with The start of where string.
627 - */
628 - return apply_filters( 'frm_prepend_and_or_where', $where, $starts_with );
629 - }
630 -
631 - /**
632 - * Prepare and save settings in styles and actions
633 - *
634 - * @since 2.05.06
635 - *
636 - * @param array|object $settings
637 - * @param string $group
638 - *
639 - * @return int|WP_Error
640 - */
641 - public static function save_settings( $settings, $group ) {
642 - $settings = (array) $settings;
643 - $settings['post_content'] = FrmAppHelper::prepare_and_encode( $settings['post_content'] );
644 -
645 - if ( empty( $settings['ID'] ) ) {
646 - unset( $settings['ID'] );
647 - }
648 -
649 - // Delete all caches for this group
650 - self::cache_delete_group( $group );
651 -
652 - return self::save_json_post( $settings );
653 - }
654 -
655 - /**
656 - * Since actions are JSON encoded, we don't want any filters messing with it.
657 - * Remove the filters and then add them back in case any posts or views are
658 - * also being imported.
659 - *
660 - * Used when saving form actions and styles
661 - *
662 - * @since 2.05.06
663 - *
664 - * @param array $settings
665 - *
666 - * @return int|WP_Error
667 - */
668 - public static function save_json_post( $settings ) {
669 - global $wp_filter;
670 -
671 - if ( isset( $wp_filter['content_save_pre'] ) ) {
672 - $filters = $wp_filter['content_save_pre'];
673 - }
674 -
675 - // Remove the balanceTags filter in case WordPress is trying to validate the XHTML
676 - remove_all_filters( 'content_save_pre' );
677 -
678 - $post = wp_insert_post( $settings );
679 -
680 - // Add the content filters back for views or posts
681 - if ( isset( $filters ) ) {
682 - $wp_filter['content_save_pre'] = $filters;
683 - }
684 -
685 - return $post;
686 - }
687 -
688 - /**
689 - * Check cache before fetching values and saving to cache
690 - *
691 - * @since 2.05.06
692 - *
693 - * @param string $cache_key The unique name for this cache.
694 - * @param string $group The name of the cache group.
695 - * @param string $query If blank, don't run a db call.
696 - * @param string $type The wpdb function to use with this query.
697 - * @param int $time Cache expiration time in seconds.
698 - *
699 - * @return mixed $results The cache or query results
700 - */
701 - public static function check_cache( $cache_key, $group = '', $query = '', $type = 'get_var', $time = 300 ) {
702 - $found = null;
703 - $results = wp_cache_get( $cache_key, $group, false, $found );
704 -
705 - if ( ( $found === true && $results !== false ) || ! $query ) {
706 - return $results;
707 - }
708 -
709 - if ( 'get_posts' === $type ) {
710 - $results = get_posts( $query );
711 - } elseif ( 'get_associative_results' === $type ) {
712 - global $wpdb;
713 - $results = $wpdb->get_results( $query, OBJECT_K ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
714 - } else {
715 - global $wpdb;
716 - $results = $wpdb->{$type}( $query );
717 - }
718 -
719 - self::set_cache( $cache_key, $results, $group, $time );
720 -
721 - return $results;
722 - }
723 -
724 - /**
725 - * @since 2.05.06
726 - *
727 - * @param string $cache_key The unique name for this cache.
728 - * @param mixed $results Cached results.
729 - * @param string $group The name of the cache group.
730 - * @param int $time Cache expiration time in seconds.
731 - *
732 - * @return void
733 - */
734 - public static function set_cache( $cache_key, $results, $group = '', $time = 300 ) {
735 - if ( FrmAppHelper::prevent_caching() ) {
736 - return;
737 - }
738 -
739 - self::add_key_to_group_cache( $cache_key, $group );
740 - wp_cache_set( $cache_key, $results, $group, $time );
741 - }
742 -
743 - /**
744 - * Keep track of the keys cached in each group so they can be deleted
745 - * in Redis and Memcache
746 - *
747 - * @since 2.05.06
748 - *
749 - * @param string $key Cache key.
750 - * @param string $group Cache group name.
751 - *
752 - * @return void
753 - */
754 - public static function add_key_to_group_cache( $key, $group ) {
755 - $cached = self::get_group_cached_keys( $group );
756 - $cached[ $key ] = $key;
757 - wp_cache_set( 'cached_keys', $cached, $group, 300 );
758 - }
759 -
760 - /**
761 - * @since 2.05.06
762 - *
763 - * @param string $group Cache group name.
764 - *
765 - * @return array
766 - */
767 - public static function get_group_cached_keys( $group ) {
768 - $cached = wp_cache_get( 'cached_keys', $group );
769 -
770 - if ( ! $cached || ! is_array( $cached ) ) {
771 - return array();
772 - }
773 -
774 - return $cached;
775 - }
776 -
777 - /**
778 - * @since 2.05.06
779 - *
780 - * @param string $cache_key Cache key to delete.
781 - * @param string $group Cache group name.
782 - *
783 - * @return void
784 - */
785 - public static function delete_cache_and_transient( $cache_key, $group = 'default' ) {
786 - delete_transient( $cache_key );
787 - wp_cache_delete( $cache_key, $group );
788 - }
789 -
790 - /**
791 - * Delete all caching in a single group
792 - *
793 - * @since 2.05.06
794 - *
795 - * @param string $group The name of the cache group.
796 - *
797 - * @return void
798 - */
799 - public static function cache_delete_group( $group ) {
800 - $cached_keys = self::get_group_cached_keys( $group );
801 -
802 - if ( ! $cached_keys ) {
803 - return;
804 - }
805 -
806 - foreach ( $cached_keys as $key ) {
807 - wp_cache_delete( $key, $group );
808 - }
809 -
810 - wp_cache_delete( 'cached_keys', $group );
811 - }
812 -
813 - /**
814 - * Checks if a DB column exists.
815 - *
816 - * @since 6.7
817 - *
818 - * @param string $table Table name without `$wpdb->prefix`.
819 - * @param string $column Column name.
820 - *
821 - * @return bool
822 - */
823 - public static function db_column_exists( $table, $column ) {
824 - global $wpdb;
825 -
826 - // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
827 - $result = $wpdb->get_results( $wpdb->prepare( 'SHOW COLUMNS FROM ' . $wpdb->prefix . $table . ' LIKE %s', $column ) );
828 - return ! empty( $result );
829 - }
323 + unset($roles);
324 + unset($frm_roles);
325 +
326 + do_action('frm_after_uninstall');
327 + }
830 328 }