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/admin/meta-boxes.php +470 -0 7.9.4 → 8.0.5 View file →
@@ -1,0 +1,470 @@
1 +<?php
2 +/**
3 + * Admin Meta Boxes
4 + *
5 + * @package GamiPress\Admin\Meta_Boxes
6 + * @author GamiPress <[email protected]>, Ruben Garcia <[email protected]>
7 + * @since 1.0.0
8 + */
9 +// Exit if accessed directly
10 +if( !defined( 'ABSPATH' ) ) exit;
11 +
12 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/achievement-type.php';
13 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/achievements.php';
14 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/points-type.php';
15 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/rank-type.php';
16 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/ranks.php';
17 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/requirements.php';
18 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/requirements-ui.php';
19 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/default-badge.php';
20 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/earners.php';
21 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/logs.php';
22 +require_once GAMIPRESS_DIR . 'includes/admin/meta-boxes/log-extra-data-ui.php';
23 +
24 +/**
25 + * Helper function to register custom meta boxes
26 + *
27 + * @since 1.0.8
28 + *
29 + * @param string $id
30 + * @param string $title
31 + * @param string|array $object_types
32 + * @param array $fields
33 + * @param array $args
34 + */
35 +function gamipress_add_meta_box( $id, $title, $object_types, $fields, $args = array() ) {
36 +
37 + // ID for hooks
38 + $hook_id = str_replace( '-', '_', $id );
39 +
40 + /**
41 + * Filter box fields to allow extend it
42 + *
43 + * @since 1.0.8
44 + *
45 + * @param array $fields Box fields
46 + * @param array $args Box args
47 + *
48 + * @return array
49 + */
50 + $fields = apply_filters( "gamipress_{$hook_id}_fields", $fields, $args );
51 +
52 + foreach( $fields as $field_id => $field ) {
53 +
54 + $fields[$field_id]['id'] = $field_id;
55 +
56 + // Support for group fields
57 + if( isset( $field['fields'] ) && is_array( $field['fields'] ) ) {
58 +
59 + foreach( $field['fields'] as $group_field_id => $group_field ) {
60 +
61 + $fields[$field_id]['fields'][$group_field_id]['id'] = $group_field_id;
62 +
63 + }
64 +
65 + }
66 +
67 + }
68 +
69 + $args = wp_parse_args( $args, array(
70 + 'vertical_tabs' => false,
71 + 'tabs' => array(),
72 + 'context' => 'normal',
73 + 'priority' => 'default',
74 + 'show_on_cb' => '',
75 + ) );
76 +
77 + /**
78 + * Filter box tabs to allow extend it
79 + *
80 + * @since 1.0.8
81 + *
82 + * @param array $tabs Box tabs
83 + * @param array $fields Box fields
84 + * @param array $args Box args
85 + *
86 + * @return array
87 + */
88 + $tabs = apply_filters( "gamipress_{$hook_id}_tabs", $args['tabs'], $fields, $args );
89 +
90 + // Parse tabs
91 + foreach( $tabs as $tab_id => $tab ) {
92 +
93 + $tabs[$tab_id]['id'] = $tab_id;
94 +
95 + }
96 +
97 + // Setup the final box arguments
98 + $box = array(
99 + 'id' => $id,
100 + 'title' => $title,
101 + 'object_types' => ! is_array( $object_types) ? array( $object_types ) : $object_types,
102 + 'tabs' => $tabs,
103 + 'vertical_tabs' => $args['vertical_tabs'],
104 + 'context' => $args['context'],
105 + 'priority' => $args['priority'],
106 + 'show_on_cb' => $args['show_on_cb'],
107 + 'classes' => 'gamipress-form gamipress-box-form',
108 + 'fields' => $fields
109 + );
110 +
111 + /**
112 + * Filter the final box args that will be passed to CMB2
113 + *
114 + * @since 1.6.9
115 + *
116 + * @param array $box Final box args
117 + * @param string $id Box id
118 + * @param string $title Box title
119 + * @param string|array $object_types Object types where box will appear
120 + * @param array $fields Box fields
121 + * @param array $tabs Box tabs
122 + * @param array $args Box args
123 + */
124 + apply_filters( "gamipress_{$hook_id}_box", $box, $id, $title, $object_types, $fields, $tabs, $args );
125 +
126 + // Instance the CMB2 box
127 + new_cmb2_box( $box );
128 +}
129 +
130 +/**
131 + * Register custom meta boxes used throughout GamiPress
132 + *
133 + * @since 1.0.0
134 + */
135 +function gamipress_init_meta_boxes() {
136 +
137 + global $post, $pagenow, $ct_table;
138 +
139 + if( ! in_array( $pagenow, array( 'post-new.php', 'post.php', 'admin.php' ) ) ) {
140 + return;
141 + }
142 +
143 + $post_type = '';
144 +
145 + // Get post type from global post
146 + if ( $post instanceof WP_Post ) {
147 + $post_type = $post->post_type;
148 + }
149 +
150 + // On post.php post ID is on GET parameters
151 + if( empty( $post_type ) && isset( $_GET['post'] ) ) {
152 + $post_type = gamipress_get_post_field( 'post_type', $_GET['post'] );
153 + }
154 +
155 + // On post-new.php and sometimes on post.php post type is on GET or POST parameters
156 + if( empty( $post_type ) && isset( $_REQUEST['post_type'] ) ) {
157 + $post_type = sanitize_text_field( $_REQUEST['post_type'] );
158 + }
159 +
160 + // Check if there is a CT view
161 + if( empty( $post_type ) && $pagenow === 'admin.php' && $ct_table ) {
162 + $post_type = $ct_table->name;
163 + }
164 +
165 + // Check if there is the edit GamiPress logs screen
166 + if( $pagenow === 'admin.php' && isset( $_GET['page'] ) && $_GET['page'] === 'edit_gamipress_logs' ) {
167 + $post_type = 'gamipress_logs';
168 + }
169 +
170 + /**
171 + * Hook to register meta boxes
172 + *
173 + * @since 1.4.7
174 + *
175 + * @param string $post_type
176 + */
177 + do_action( 'gamipress_init_meta_boxes', $post_type );
178 +
179 + /**
180 + * Hook to register meta boxes
181 + *
182 + * @since 1.4.7
183 + */
184 + do_action( "gamipress_init_{$post_type}_meta_boxes" );
185 +
186 +}
187 +add_action( 'cmb2_admin_init', 'gamipress_init_meta_boxes' );
188 +
189 +function gamipress_remove_meta_boxes() {
190 +
191 + remove_meta_box( 'slugdiv', 'points-type', 'normal' );
192 + remove_meta_box( 'slugdiv', 'achievement-type', 'normal' );
193 + remove_meta_box( 'slugdiv', 'rank-type', 'normal' );
194 +
195 +}
196 +add_action( 'admin_menu', 'gamipress_remove_meta_boxes' );
197 +
198 +/**
199 + * Filters the admin post thumbnail HTML markup to return.
200 + *
201 + * @since 2.9.0
202 + *
203 + * @param string $content Admin post thumbnail HTML markup.
204 + * @param int $post_id Post ID.
205 + * @param int|null $thumbnail_id Thumbnail attachment ID, or null if there isn't one.
206 + */
207 +function gamipress_admin_post_thumbnail_html( $content, $post_id, $thumbnail_id ) {
208 +
209 + $post_type = gamipress_get_post_type( $post_id );
210 +
211 + switch( $post_type ) {
212 + case 'achievement-type':
213 + $content .= '<p class="howto">' . esc_html__( 'This image will be used for all achievements that do not have an image.', 'gamipress' ) . '</p>';
214 + break;
215 + case 'rank-type':
216 + $content .= '<p class="howto">' . esc_html__( 'This image will be used for all ranks that do not have an image.', 'gamipress' ) . '</p>';
217 + break;
218 + }
219 +
220 + return $content;
221 +
222 +}
223 +add_filter( 'admin_post_thumbnail_html', 'gamipress_admin_post_thumbnail_html', 10, 3 );
224 +
225 +// Options callback for select2 fields assigned to posts
226 +function gamipress_options_cb_posts( $field ) {
227 +
228 + $value = $field->escaped_value;
229 + $options = array();
230 +
231 + if( ! empty( $value ) ) {
232 + if( ! is_array( $value ) ) {
233 + $value = array( $value );
234 + }
235 +
236 + foreach( $value as $post_id ) {
237 + $options[$post_id] = get_post_field( 'post_title', $post_id ) . ' (#' . $post_id . ')';
238 + }
239 + }
240 +
241 + return $options;
242 +
243 +}
244 +
245 +// Options callback for select2 fields assigned to users
246 +function gamipress_options_cb_users( $field ) {
247 +
248 + $value = $field->escaped_value;
249 + $options = array();
250 +
251 + if( ! empty( $value ) ) {
252 + if( ! is_array( $value ) ) {
253 + $value = array( $value );
254 + }
255 +
256 + foreach( $value as $user_id ) {
257 + $user_data = get_userdata($user_id);
258 +
259 + $options[$user_id] = $user_data->user_login;
260 + }
261 + }
262 +
263 + return $options;
264 +
265 +}
266 +
267 +// Options callback for WordPress roles
268 +function gamipress_options_cb_roles( $field ) {
269 +
270 + $options = array();
271 +
272 + $editable_roles = get_editable_roles();
273 +
274 + $field->args['excluded_roles'] = ( isset( $field->args['excluded_roles'] ) ? $field->args['excluded_roles'] : array() );
275 +
276 + // Ensure excluded roles as array
277 + if( ! is_array( $field->args['excluded_roles'] ) )
278 + $field->args['excluded_roles'] = array( $field->args['excluded_roles'] );
279 +
280 + foreach ( $editable_roles as $role => $details ) {
281 +
282 + // Skip excluded roles
283 + if( in_array( $role, $field->args['excluded_roles'] ) )
284 + continue;
285 +
286 + $options[$role] = translate_user_role( $details['name'] );
287 +
288 + }
289 +
290 + return $options;
291 +
292 +}
293 +
294 +/**
295 + * Helper function to enable a checkbox when value was not stored
296 + */
297 +function gamipress_cmb2_checkbox_enabled_by_default( $field_args, $field ) {
298 +
299 + if( get_post_field( 'post_status', $field->object_id ) === 'auto-draft' ) {
300 + return '1';
301 + }
302 +
303 + return '';
304 +
305 +}
306 +
307 +/**
308 + * Helper function to avoid errors with default param
309 + */
310 +function gamipress_site_name_default_cb( $field_args, $field ) {
311 +
312 + return get_bloginfo( 'name' );
313 +
314 +}
315 +
316 +/**
317 + * Override the title/content field retrieval so CMB2 doesn't look in post-meta.
318 + */
319 +function gamipress_cmb2_override_post_title_display( $data, $post_id ) {
320 +
321 + global $ct_cmb2_override;
322 +
323 + // Prevent to override on custom tables
324 + if( $ct_cmb2_override === true ) {
325 + return $data;
326 + }
327 +
328 + if( get_post_field( 'post_status', $post_id ) === 'auto-draft' ) {
329 + return '';
330 + }
331 +
332 + return get_post_field( 'post_title', $post_id );
333 +
334 +}
335 +add_filter( 'cmb2_override_post_title_meta_value', 'gamipress_cmb2_override_post_title_display', 10, 2 );
336 +
337 +function gamipress_cmb2_override_post_name_display( $data, $post_id ) {
338 +
339 + global $ct_cmb2_override;
340 +
341 + // Prevent to override on custom tables
342 + if( $ct_cmb2_override === true ) {
343 + return $data;
344 + }
345 +
346 + return get_post_field( 'post_name', $post_id );
347 +
348 +}
349 +add_filter( 'cmb2_override_post_name_meta_value', 'gamipress_cmb2_override_post_name_display', 10, 2 );
350 +
351 +function gamipress_cmb2_override_menu_order_display( $data, $post_id ) {
352 +
353 + global $ct_cmb2_override;
354 +
355 + // Prevent to override on custom tables
356 + if( $ct_cmb2_override === true ) {
357 + return $data;
358 + }
359 +
360 + // Code has been moved to gamipress_get_rank_priority() on 1.3.9
361 +
362 + return gamipress_get_rank_priority( $post_id );
363 +
364 +}
365 +add_filter( 'cmb2_override_menu_order_meta_value', 'gamipress_cmb2_override_menu_order_display', 10, 2 );
366 +
367 +/*
368 + * WP will handle the saving for us, so don't save title/content to meta.
369 + */
370 +add_filter( 'cmb2_override_post_title_meta_save', '__return_true' );
371 +add_filter( 'cmb2_override_post_name_meta_save', '__return_true' );
372 +add_filter( 'cmb2_override_menu_order_meta_save', '__return_true' );
373 +
374 +// Options callback to return achievement types as options
375 +function gamipress_options_cb_achievement_types( $field ) {
376 +
377 + // Setup a custom array of achievement types
378 +
379 + // Custom option none label
380 + $field->args['option_none_label'] = ( isset( $field->args['option_none_label'] ) ? $field->args['option_none_label'] : __( 'Choose an achievement type', 'gamipress' ) );
381 +
382 + $options = gamipress_options_cb_init_options( $field );
383 +
384 + foreach ( gamipress_get_achievement_types() as $slug => $data ) {
385 + $options[$slug] = $data['plural_name'];
386 + }
387 +
388 + return $options;
389 +
390 +}
391 +
392 +// Options callback to return points types as options
393 +function gamipress_options_cb_points_types( $field ) {
394 +
395 + // Setup a custom array of points types
396 +
397 + // Custom option none label
398 + $field->args['option_none_label'] = ( isset( $field->args['option_none_label'] ) ? $field->args['option_none_label'] : __( 'Choose a points type', 'gamipress' ) );
399 +
400 + $options = gamipress_options_cb_init_options( $field );
401 +
402 + foreach ( gamipress_get_points_types() as $slug => $data ) {
403 + $options[$slug] = $data['plural_name'];
404 + }
405 +
406 + return $options;
407 +
408 +}
409 +
410 +// Options callback to return rank types as options
411 +function gamipress_options_cb_rank_types( $field ) {
412 +
413 + // Setup a custom array of rank types
414 +
415 + // Custom option none label
416 + $field->args['option_none_label'] = ( isset( $field->args['option_none_label'] ) ? $field->args['option_none_label'] : __( 'Choose a rank type', 'gamipress' ) );
417 +
418 + $options = gamipress_options_cb_init_options( $field );
419 +
420 + foreach ( gamipress_get_rank_types() as $slug => $data ) {
421 + $options[$slug] = $data['plural_name'];
422 + }
423 +
424 + return $options;
425 +
426 +}
427 +
428 +// Options callback to return log types as options
429 +function gamipress_options_cb_log_types( $field ) {
430 +
431 + // Setup a custom array of log types
432 +
433 + // Custom option none label
434 + $field->args['option_none_label'] = ( isset( $field->args['option_none_label'] ) ? $field->args['option_none_label'] : __( 'Choose a log type', 'gamipress' ) );
435 +
436 + $options = gamipress_options_cb_init_options( $field );
437 +
438 + // Prepend the log types as options
439 + $options = array_merge( $options, gamipress_get_log_types() );
440 +
441 + return $options;
442 +
443 +}
444 +
445 +// Common callback for options_cb functions that support custom args
446 +function gamipress_options_cb_init_options( $field ) {
447 +
448 + $options = array();
449 +
450 + // Default args
451 +
452 + // option_none = false
453 + $field->args['option_none'] = ( isset( $field->args['option_none'] ) ? $field->args['option_none'] : false );
454 + // option_none_label = __( 'Choose an option', 'gamipress' )
455 + $field->args['option_none_label'] = ( isset( $field->args['option_none_label'] ) ? $field->args['option_none_label'] : __( 'Choose an option', 'gamipress' ) );
456 +
457 + // option_all = true
458 + $field->args['option_all'] = ( isset( $field->args['option_all'] ) ? $field->args['option_all'] : true );
459 + // option_all_label = __( 'All', 'gamipress' )
460 + $field->args['option_all_label'] = ( isset( $field->args['option_all_label'] ) ? $field->args['option_all_label'] : __( 'All', 'gamipress' ) );
461 +
462 + // Check if option_none is set to true (by default option_none is set to false)
463 + if( $field->args['option_none'] ) $options[''] = $field->args['option_none_label'];
464 +
465 + // Check if option_all is set to true (by default option_all is set to true)
466 + if( $field->args['option_all'] ) $options['all'] = $field->args['option_all_label'];
467 +
468 + return $options;
469 +
470 +}