PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / 8.0.5
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI v8.0.5
8.0.5 8.0.4 8.0.3 8.0.1 8.0.2 8.0.0 7.9.9.7 7.9.9.6 7.9.9.5 7.9.9.4 7.9.9.3 7.9.9.2 7.9.9.1 7.9.9 7.9.8 7.9.7 7.9.6 7.9.5 7.9.4 7.9.3 7.9.2 7.9.1 7.9.0 7.8.9 7.8.8 All 47 releases
← All changes | includes/shortcodes/gamipress_earnings.php +628 -0 7.9.2 → 8.0.5 View file →
@@ -1,0 +1,628 @@
1 +<?php
2 +/**
3 + * GamiPress Earnings Shortcode
4 + *
5 + * @package GamiPress\Shortcodes\Shortcode\GamiPress_Earnings
6 + * @author GamiPress <[email protected]>, Ruben Garcia <[email protected]>
7 + * @since 1.3.9
8 + */
9 +// Exit if accessed directly
10 +if( !defined( 'ABSPATH' ) ) exit;
11 +
12 +/**
13 + * Register [gamipress_earnings] shortcode
14 + *
15 + * @since 1.3.9
16 + */
17 +function gamipress_register_earnings_shortcode() {
18 +
19 + gamipress_register_shortcode( 'gamipress_earnings', array(
20 + 'name' => __( 'User Earnings', 'gamipress' ),
21 + 'description' => __( 'Display a list of user earnings.', 'gamipress' ),
22 + 'group' => 'gamipress',
23 + 'output_callback' => 'gamipress_earnings_shortcode',
24 + 'tabs' => array(
25 + 'general' => array(
26 + 'icon' => 'dashicons-admin-generic',
27 + 'title' => __( 'General', 'gamipress' ),
28 + 'fields' => array(
29 + 'current_user',
30 + 'user_id',
31 + 'force_responsive',
32 + 'limit',
33 + 'pagination',
34 + 'order',
35 + 'include',
36 + 'exclude',
37 + ),
38 + ),
39 + 'points' => array(
40 + 'icon' => 'dashicons-star-filled',
41 + 'title' => __( 'Points', 'gamipress' ),
42 + 'fields' => array(
43 + 'points',
44 + 'points_types',
45 + 'awards',
46 + 'deducts'
47 + ),
48 + ),
49 + 'achievements' => array(
50 + 'icon' => 'dashicons-awards',
51 + 'title' => __( 'Achievements', 'gamipress' ),
52 + 'fields' => array(
53 + 'achievements',
54 + 'achievement_types',
55 + 'steps',
56 + 'achievements_without_points',
57 + ),
58 + ),
59 + 'ranks' => array(
60 + 'icon' => 'dashicons-rank',
61 + 'title' => __( 'Ranks', 'gamipress' ),
62 + 'fields' => array(
63 + 'ranks',
64 + 'rank_types',
65 + 'rank_requirements',
66 + ),
67 + ),
68 + ),
69 + 'fields' => array(
70 + 'current_user' => array(
71 + 'name' => __( 'Current User', 'gamipress' ),
72 + 'tooltip' => __( 'Show only earned items of the current logged in user.', 'gamipress' ),
73 + 'label_cb' => 'cmb_tooltip_label_cb',
74 + 'type' => 'checkbox',
75 + 'classes' => 'gamipress-switch',
76 + 'default' => 'yes',
77 + ),
78 + 'user_id' => array(
79 + 'name' => __( 'User', 'gamipress' ),
80 + 'tooltip' => __( 'Show only earned items by a specific user. Leave blank to show earned items of all users.', 'gamipress' ),
81 + 'label_cb' => 'cmb_tooltip_label_cb',
82 + 'type' => 'select',
83 + 'default' => '',
84 + 'options_cb' => 'gamipress_options_cb_users'
85 + ),
86 + 'force_responsive' => array(
87 + 'name' => __( 'Force Responsive', 'gamipress' ),
88 + 'tooltip' => __( 'Force to display the earnings table with the responsive style.', 'gamipress' ),
89 + 'label_cb' => 'cmb_tooltip_label_cb',
90 + 'type' => 'checkbox',
91 + 'classes' => 'gamipress-switch',
92 + ),
93 + 'limit' => array(
94 + 'name' => __( 'Limit', 'gamipress' ),
95 + 'tooltip' => __( 'Number of items to display.', 'gamipress' ),
96 + 'label_cb' => 'cmb_tooltip_label_cb',
97 + 'type' => 'text',
98 + 'default' => 10,
99 + ),
100 + 'pagination' => array(
101 + 'name' => __( 'Enable Pagination', 'gamipress' ),
102 + 'tooltip' => __( 'Show pagination links to navigate through all earned items.', 'gamipress' ),
103 + 'label_cb' => 'cmb_tooltip_label_cb',
104 + 'type' => 'checkbox',
105 + 'classes' => 'gamipress-switch',
106 + 'default' => 'yes',
107 + ),
108 + 'order' => array(
109 + 'name' => __( 'Order', 'gamipress' ),
110 + 'tooltip' => __( 'Sort order.', 'gamipress' ),
111 + 'label_cb' => 'cmb_tooltip_label_cb',
112 + 'type' => 'select',
113 + 'options' => array( 'DESC' => __( 'Newest', 'gamipress' ), 'ASC' => __( 'Older', 'gamipress' ) ),
114 + 'default' => 'DESC',
115 + ),
116 + 'include' => array(
117 + 'name' => __( 'Include', 'gamipress' ),
118 + 'tooltip' => __( 'Comma-separated list of specific earnings IDs to include.', 'gamipress' ),
119 + 'label_cb' => 'cmb_tooltip_label_cb',
120 + 'type' => 'text',
121 + ),
122 + 'exclude' => array(
123 + 'name' => __( 'Exclude', 'gamipress' ),
124 + 'tooltip' => __( 'Comma-separated list of specific earnings IDs to exclude.', 'gamipress' ),
125 + 'label_cb' => 'cmb_tooltip_label_cb',
126 + 'type' => 'text',
127 + ),
128 +
129 + // Points types
130 +
131 + 'points' => array(
132 + 'name' => __( 'Show Points', 'gamipress' ),
133 + 'tooltip' => __( 'Show points earned and deducted.', 'gamipress' ),
134 + 'label_cb' => 'cmb_tooltip_label_cb',
135 + 'type' => 'checkbox',
136 + 'classes' => 'gamipress-switch',
137 + 'default' => 'yes',
138 + ),
139 + 'points_types' => array(
140 + 'name' => __( 'Points Type(s)', 'gamipress' ),
141 + 'tooltip' => __( 'Points type(s) to display.', 'gamipress' ),
142 + 'label_cb' => 'cmb_tooltip_label_cb',
143 + 'shortcode_desc' => __( 'Single or comma-separated list of points type(s) to display.', 'gamipress' ),
144 + 'type' => 'advanced_select',
145 + 'multiple' => true,
146 + 'classes' => 'gamipress-selector',
147 + 'attributes' => array(
148 + 'data-placeholder' => __( 'Default: All', 'gamipress' ),
149 + ),
150 + 'options_cb' => 'gamipress_options_cb_points_types',
151 + 'default' => 'all',
152 + ),
153 + 'awards' => array(
154 + 'name' => __( 'Show Points Awards', 'gamipress' ),
155 + 'tooltip' => __( 'Show points awarded.', 'gamipress' ),
156 + 'label_cb' => 'cmb_tooltip_label_cb',
157 + 'type' => 'checkbox',
158 + 'classes' => 'gamipress-switch',
159 + 'default' => 'yes',
160 + ),
161 + 'deducts' => array(
162 + 'name' => __( 'Show Points Deductions', 'gamipress' ),
163 + 'tooltip' => __( 'Show points deducted.', 'gamipress' ),
164 + 'label_cb' => 'cmb_tooltip_label_cb',
165 + 'type' => 'checkbox',
166 + 'classes' => 'gamipress-switch',
167 + 'default' => 'yes',
168 + ),
169 +
170 + // Achievement types
171 +
172 + 'achievements' => array(
173 + 'name' => __( 'Show Achievements', 'gamipress' ),
174 + 'tooltip' => __( 'Show achievements earned.', 'gamipress' ),
175 + 'label_cb' => 'cmb_tooltip_label_cb',
176 + 'type' => 'checkbox',
177 + 'classes' => 'gamipress-switch',
178 + 'default' => 'yes',
179 + ),
180 + 'achievement_types' => array(
181 + 'name' => __( 'Achievement Type(s)', 'gamipress' ),
182 + 'tooltip' => __( 'Achievements type(s) to display.', 'gamipress' ),
183 + 'label_cb' => 'cmb_tooltip_label_cb',
184 + 'shortcode_desc' => __( 'Single or comma-separated list of achievements type(s) to display.', 'gamipress' ),
185 + 'type' => 'advanced_select',
186 + 'multiple' => true,
187 + 'classes' => 'gamipress-selector',
188 + 'attributes' => array(
189 + 'data-placeholder' => __( 'Default: All', 'gamipress' ),
190 + ),
191 + 'options_cb' => 'gamipress_options_cb_achievement_types',
192 + 'default' => 'all',
193 + ),
194 + 'steps' => array(
195 + 'name' => __( 'Show Steps', 'gamipress' ),
196 + 'tooltip' => __( 'Show steps completed.', 'gamipress' ),
197 + 'label_cb' => 'cmb_tooltip_label_cb',
198 + 'type' => 'checkbox',
199 + 'classes' => 'gamipress-switch',
200 + 'default' => 'yes',
201 + ),
202 + 'achievements_without_points' => array(
203 + 'name' => __( 'Show Achievements Without Points', 'gamipress' ),
204 + 'tooltip' => __( 'Show achievements that do not award points.', 'gamipress' ),
205 + 'label_cb' => 'cmb_tooltip_label_cb',
206 + 'type' => 'checkbox',
207 + 'classes' => 'gamipress-switch',
208 + 'default' => 'yes',
209 + ),
210 +
211 + // Rank types
212 +
213 + 'ranks' => array(
214 + 'name' => __( 'Show Ranks', 'gamipress' ),
215 + 'tooltip' => __( 'Show ranks reached.', 'gamipress' ),
216 + 'label_cb' => 'cmb_tooltip_label_cb',
217 + 'type' => 'checkbox',
218 + 'classes' => 'gamipress-switch',
219 + 'default' => 'yes',
220 + ),
221 + 'rank_types' => array(
222 + 'name' => __( 'Rank Type(s)', 'gamipress' ),
223 + 'tooltip' => __( 'Ranks type(s) to display.', 'gamipress' ),
224 + 'label_cb' => 'cmb_tooltip_label_cb',
225 + 'shortcode_desc' => __( 'Single or comma-separated list of ranks type(s) to display.', 'gamipress' ),
226 + 'type' => 'advanced_select',
227 + 'multiple' => true,
228 + 'classes' => 'gamipress-selector',
229 + 'attributes' => array(
230 + 'data-placeholder' => __( 'Default: All', 'gamipress' ),
231 + ),
232 + 'options_cb' => 'gamipress_options_cb_rank_types',
233 + 'default' => 'all',
234 + ),
235 + 'rank_requirements' => array(
236 + 'name' => __( 'Show Rank Requirements', 'gamipress' ),
237 + 'tooltip' => __( 'Show rank requirements completed.', 'gamipress' ),
238 + 'label_cb' => 'cmb_tooltip_label_cb',
239 + 'type' => 'checkbox',
240 + 'classes' => 'gamipress-switch',
241 + 'default' => 'yes',
242 + ),
243 + ),
244 + ) );
245 +
246 +}
247 +add_action( 'init', 'gamipress_register_earnings_shortcode' );
248 +
249 +/**
250 + * User Earnings Shortcode
251 + *
252 + * @since 1.3.9
253 + *
254 + * @param array $atts Shortcode attributes
255 + * @param string $content Shortcode content
256 + *
257 + * @return string HTML markup
258 + */
259 +function gamipress_earnings_shortcode( $atts = array(), $content = '' ) {
260 +
261 + global $gamipress_template_args;
262 +
263 + // Initialize GamiPress template args global
264 + $gamipress_template_args = array();
265 +
266 + $shortcode = 'gamipress_earnings';
267 +
268 + $atts = shortcode_atts( gamipress_earnings_shortcode_defaults(), $atts, $shortcode );
269 +
270 + gamipress_enqueue_scripts();
271 +
272 + // On network wide active installs, we need to switch to main blog mostly for posts permalinks and thumbnails
273 + $blog_id = gamipress_switch_to_main_site_if_network_wide_active();
274 +
275 + // Force to set current user as user ID
276 + if( $atts['current_user'] === 'yes' ) {
277 +
278 + /**
279 + * Filter to override shortcode workflow with not logged in users when current user is set to yes
280 + *
281 + * @since 1.7.4.2
282 + *
283 + * @param bool $empty_if_not_logged_in Final workflow to follow
284 + * @param array $atts Shortcode attributes
285 + * @param string $content Shortcode content
286 + */
287 + $empty_if_not_logged_in = apply_filters( 'gamipress_earnings_shortcode_empty_if_not_logged_in', true, $atts, $content );
288 +
289 + // Return if current_user is set to yes and current user is a guest
290 + if( get_current_user_id() === 0 && $empty_if_not_logged_in )
291 + return '';
292 +
293 + $atts['user_id'] = get_current_user_id();
294 +
295 + }
296 +
297 + // GamiPress template args global
298 + $gamipress_template_args = $atts;
299 +
300 + // Earnings query
301 + $gamipress_template_args['query'] = gamipress_earnings_shortcode_query( $atts );
302 +
303 + if( ! $gamipress_template_args['query'] ) {
304 + return '';
305 + }
306 +
307 + // Earnings columns
308 + $gamipress_template_args['columns'] = array();
309 +
310 + if( absint( $atts['user_id'] ) === 0 ) {
311 + $gamipress_template_args['columns']['user'] = __( 'User', 'gamipress' );
312 + }
313 +
314 + // Previous column label, keep for translation
315 + $gamipress_template_args['columns']['thumbnail'] = __( 'Thumbnail', 'gamipress' );
316 +
317 + $gamipress_template_args['columns']['thumbnail'] = __( 'Image', 'gamipress' );
318 + $gamipress_template_args['columns']['description'] = __( 'Description', 'gamipress' );
319 + $gamipress_template_args['columns']['points'] = __( 'Points', 'gamipress' );
320 + $gamipress_template_args['columns']['date'] = __( 'Date', 'gamipress' );
321 + $gamipress_template_args['columns']['actions'] = __( 'Actions', 'gamipress' );
322 +
323 +
324 + // Render the earnings template
325 + ob_start();
326 + gamipress_get_template_part( 'earnings' );
327 + $output = ob_get_clean();
328 +
329 + // If switched to blog, return back to que current blog
330 + if( $blog_id !== get_current_blog_id() && is_multisite() ) {
331 + restore_current_blog();
332 + }
333 +
334 + /**
335 + * Filter to override shortcode output
336 + *
337 + * @since 1.6.5
338 + *
339 + * @param string $output Final output
340 + * @param array $atts Shortcode attributes
341 + * @param string $content Shortcode content
342 + */
343 + return apply_filters( 'gamipress_earnings_shortcode_output', $output, $atts, $content );
344 +
345 +}
346 +
347 +/**
348 + * User Earnings Shortcode Query
349 + *
350 + * @since 1.4.9
351 + *
352 + * @param array $args Query arguments
353 + *
354 + * @return CT_Query
355 + */
356 +function gamipress_earnings_shortcode_query( $args = array () ) {
357 +
358 + // Query args
359 + $query_args = array(
360 + 'orderby' => 'date',
361 + 'order' => $args['order'],
362 + 'items_per_page' => $args['limit'],
363 + 'paged' => max( 1, get_query_var( 'paged' ) )
364 + );
365 +
366 + $query_args['post_type'] = array();
367 + $query_args['points_type'] = array();
368 + $query_args['post_type__not_in'] = array();
369 + $query_args['parent_post_type'] = array();
370 +
371 + // User
372 + if( isset( $args['user_id'] ) && absint( $args['user_id'] ) !== 0 ) {
373 + $query_args['user_id'] = $args['user_id'];
374 + }
375 +
376 + // Build $include array
377 + if ( ! is_array( $args['include'] ) && ! empty( $args['include'] ) ) {
378 + $include = explode( ',', $args['include'] );
379 + }
380 +
381 + // Build $exclude array
382 + if ( ! is_array( $args['exclude'] ) && ! empty( $args['exclude'] ) ) {
383 + $exclude = explode( ',', $args['exclude'] );
384 + }
385 +
386 + // Include certain user earnings
387 + if ( isset( $include ) && ! empty( $include ) ) {
388 + $query_args[ 'user_earning__in' ] = $include;
389 + }
390 +
391 + // Exclude certain user earnings
392 + if ( isset( $exclude ) && ! empty( $exclude ) ) {
393 + $query_args[ 'user_earning__not_in' ] = $exclude;
394 + }
395 +
396 + // Points types
397 + if( $args['points'] === 'yes' ) {
398 +
399 + if( $args['points_types'] === 'all') {
400 + $query_args['points_type'] = gamipress_get_points_types_slugs();
401 + } else {
402 + $point_types = explode( ',', $args['points_types'] );
403 + $query_args['points_type'] = gamipress_sanitize_point_types_slugs_array( $point_types );
404 + }
405 +
406 + // For custom earnings points to the points type
407 + $query_args['post_type'][] = 'points-type';
408 +
409 + // Points awards
410 + if( $args['awards'] === 'yes' ) {
411 + $query_args['post_type'][] = 'points-award';
412 + } else {
413 + $query_args['post_type__not_in'][] = 'points-award';
414 + }
415 +
416 + // Points deducts
417 + if( $args['deducts'] === 'yes' ) {
418 + $query_args['post_type'][] = 'points-deduct';
419 + } else {
420 + $query_args['post_type__not_in'][] = 'points-deduct';
421 + }
422 +
423 + } else {
424 + $query_args['post_type__not_in'][] = 'points-type';
425 + $query_args['post_type__not_in'][] = 'points-award';
426 + $query_args['post_type__not_in'][] = 'points-deduct';
427 + }
428 +
429 + // Achievement types
430 + if( $args['achievements'] === 'yes' ) {
431 +
432 + if( $args['achievement_types'] === 'all') {
433 + $achievement_types = gamipress_get_achievement_types_slugs();
434 + } else {
435 + $achievement_types = explode( ',', $args['achievement_types'] );
436 + $achievement_types = gamipress_sanitize_achievement_types_slugs_array( $achievement_types );
437 + }
438 + $query_args['post_type'] = array_merge( $query_args['post_type'], $achievement_types );
439 +
440 + // Step
441 + if( $args['steps'] === 'yes' ) {
442 + if( $args['achievement_types'] === 'all') {
443 + $query_args['post_type'][] = 'step';
444 + } else {
445 + $query_args['parent_post_type'] = array_merge( $query_args['parent_post_type'], $achievement_types );
446 + }
447 + } else {
448 + $query_args['post_type__not_in'][] = 'step';
449 + }
450 +
451 + } else {
452 + $query_args['post_type__not_in'] = array_merge( $query_args['post_type__not_in'], gamipress_get_achievement_types_slugs() );
453 + $query_args['post_type__not_in'][] = 'step';
454 + }
455 +
456 + // Rank types
457 + if( $args['ranks'] === 'yes' ) {
458 +
459 + if( $args['rank_types'] === 'all') {
460 + $rank_types = gamipress_get_rank_types_slugs();
461 + } else {
462 + $rank_types = explode( ',', $args['rank_types'] );
463 + $rank_types = gamipress_sanitize_rank_types_slugs_array( $rank_types );
464 + }
465 +
466 + $query_args['post_type'] = array_merge( $query_args['post_type'], $rank_types );
467 +
468 + // Rank requirements
469 + if( $args['rank_requirements'] === 'yes' ) {
470 + if( $args['rank_types'] === 'all') {
471 + $query_args['post_type'][] = 'rank-requirement';
472 + } else {
473 + $query_args['parent_post_type'] = array_merge( $query_args['parent_post_type'], $rank_types );
474 + }
475 + } else {
476 + $query_args['post_type__not_in'][] = 'rank-requirement';
477 + }
478 +
479 + } else {
480 + $query_args['post_type__not_in'] = array_merge( $query_args['post_type__not_in'], gamipress_get_rank_types_slugs() );
481 + $query_args['post_type__not_in'][] = 'rank-requirement';
482 + }
483 +
484 + // Remove types that has 'all' value
485 + foreach( $query_args['post_type'] as $index => $type ) {
486 + if( $type === 'all' ) {
487 + unset( $query_args['post_type'][$index] );
488 + }
489 + }
490 +
491 + // Return if not types selected
492 + if( empty( $query_args['post_type'] ) ) {
493 + return false;
494 + }
495 +
496 + if( ! empty( $query_args['points_type'] ) ) {
497 + $query_args['force_types'] = true;
498 + }
499 +
500 + // If looking to show achievements that do not award any points, then need to add the empty points type value and force the post and points types queries
501 + if( $args['achievements_without_points'] === 'yes' ) {
502 + $query_args['points_type'][] = '';
503 + $query_args['force_types'] = true;
504 + }
505 +
506 + /**
507 + * Filters earnings shortcode query args
508 + *
509 + * @since 2.0.7
510 + *
511 + * @param array $query_args Query args to be passed to CT_Query
512 + * @param array $args Function received args
513 + *
514 + * @return array
515 + */
516 + $query_args = apply_filters( 'gamipress_earnings_shortcode_query_args', $query_args, $args );
517 +
518 + // Setup table
519 + $ct_table = ct_setup_table( 'gamipress_user_earnings' );
520 +
521 + // Sanitize query args
522 + $query_args = gamipress_sanitize_query_args( $query_args, gamipress_user_earnings_query_vars_rules() );
523 +
524 + return new CT_Query( $query_args );
525 +
526 +}
527 +
528 +/**
529 + * Earnings shortcode defaults attributes values
530 + *
531 + * @since 7.1.6
532 + *
533 + * @return array
534 + */
535 +function gamipress_earnings_shortcode_defaults() {
536 +
537 + return apply_filters( 'gamipress_earnings_shortcode_defaults', array(
538 + 'current_user' => 'yes',
539 + 'user_id' => '0',
540 + 'force_responsive' => '',
541 + 'limit' => '10',
542 + 'pagination' => 'yes',
543 + 'order' => 'DESC',
544 + 'include' => '',
545 + 'exclude' => '',
546 + 'points' => 'yes',
547 + 'points_types' => 'all',
548 + 'awards' => 'yes',
549 + 'deducts' => 'yes',
550 + 'achievements' => 'yes',
551 + 'achievement_types' => 'all',
552 + 'steps' => 'yes',
553 + 'achievements_without_points' => 'yes',
554 + 'ranks' => 'yes',
555 + 'rank_types' => 'all',
556 + 'rank_requirements' => 'yes',
557 + ) );
558 +
559 +}
560 +
561 +/**
562 + * User Earnings query vars rules
563 + *
564 + * @since 7.8.8
565 + *
566 + * @return array
567 + */
568 +function gamipress_user_earnings_query_vars_rules() {
569 +
570 + // Setup table
571 + $ct_table = ct_setup_table( 'gamipress_user_earnings' );
572 +
573 + $rules = apply_filters( 'gamipress_user_earnings_query_vars_rules', array(
574 + // Query fields
575 + 'orderby' => array(
576 + 'type' => 'string',
577 + 'sanitize' => 'text',
578 + 'allowed_values' => array_keys( $ct_table->db->schema->fields ),
579 + ),
580 + 'order' => array(
581 + 'type' => 'string',
582 + 'sanitize' => 'uppercase',
583 + 'allowed_values' => array( 'ASC', 'DESC' ),
584 + ),
585 + 'items_per_page' => array(
586 + 'type' => 'integer',
587 + ),
588 + 'paged' => array(
589 + 'type' => 'integer',
590 + ),
591 + // Earning fields
592 + 'user_id' => array(
593 + 'type' => 'integer',
594 + ),
595 + 'user_earning__in' => array(
596 + 'type' => 'array',
597 + 'sanitize' => 'integer',
598 + ),
599 + 'user_earning__not_in' => array(
600 + 'type' => 'array',
601 + 'sanitize' => 'integer',
602 + ),
603 + 'post_type' => array(
604 + 'type' => 'array',
605 + 'sanitize' => 'text',
606 + ),
607 + 'post_type__not_in' => array(
608 + 'type' => 'array',
609 + 'sanitize' => 'text',
610 + ),
611 + 'parent_post_type' => array(
612 + 'type' => 'array',
613 + 'sanitize' => 'text',
614 + ),
615 + 'points_type' => array(
616 + 'type' => 'array',
617 + 'sanitize' => 'text',
618 + ),
619 + 'force_types' => array(
620 + 'type' => 'boolean',
621 + ),
622 + ) );
623 +
624 + ct_reset_setup_table();
625 +
626 + return $rules;
627 +
628 +}