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/network.php +455 -0 7.9.9.2 → 8.0.5 View file →
@@ -1,0 +1,455 @@
1 +<?php
2 +/**
3 + * Network
4 + *
5 + * @package GamiPress\Network
6 + * @author GamiPress <[email protected]>, Ruben Garcia <[email protected]>
7 + * @since 1.4.0
8 + */
9 +// Exit if accessed directly
10 +if( !defined( 'ABSPATH' ) ) exit;
11 +
12 +/**
13 + * Initializes GamiPress on multisite installs
14 + *
15 + * @since 1.4.0
16 + */
17 +function gamipress_init_multisite() {
18 +
19 + global $wpdb;
20 +
21 + if( is_multisite() ) {
22 +
23 + // Update GamiPress database if network wide active
24 + if( gamipress_is_network_wide_active() ) {
25 +
26 + // Setup WordPress database tables
27 + GamiPress()->db->posts = $wpdb->base_prefix . 'posts';
28 + GamiPress()->db->postmeta = $wpdb->base_prefix . 'postmeta';
29 + GamiPress()->db->users = $wpdb->base_prefix . 'users';
30 + GamiPress()->db->usermeta = $wpdb->base_prefix . 'usermeta';
31 +
32 + // Setup GamiPress database tables
33 + GamiPress()->db->logs = $wpdb->base_prefix . 'gamipress_logs';
34 + GamiPress()->db->logs_meta = $wpdb->base_prefix . 'gamipress_logs_meta';
35 + GamiPress()->db->user_earnings = $wpdb->base_prefix . 'gamipress_user_earnings';
36 + GamiPress()->db->user_earnings_meta = $wpdb->base_prefix . 'gamipress_user_earnings_meta';
37 +
38 + }
39 +
40 + }
41 +
42 +}
43 +add_action( 'gamipress_init', 'gamipress_init_multisite', 1 );
44 +
45 +/**
46 + * Create array of blog ids in network
47 + *
48 + * @since 1.0.0
49 + *
50 + * @return array Array of blog_ids
51 + */
52 +function gamipress_get_network_site_ids() {
53 +
54 + global $wpdb;
55 +
56 + $cache = gamipress_get_cache( 'gamipress_blog_ids', false, false );
57 +
58 + if( is_multisite() ) {
59 +
60 + // If result already cached, return it
61 + if( is_array( $cache ) ) {
62 + $blog_ids = $cache;
63 + } else {
64 + $blog_ids = $wpdb->get_results( "SELECT blog_id FROM " . $wpdb->base_prefix . "blogs" );
65 +
66 + gamipress_set_cache( 'gamipress_blog_ids', $blog_ids );
67 + }
68 + foreach ($blog_ids as $key => $value ) {
69 + $sites[] = $value->blog_id;
70 + }
71 +
72 + } else {
73 + $sites[] = get_current_blog_id();
74 + }
75 +
76 + return $sites;
77 +
78 +}
79 +
80 +/**
81 + * Replace per site queries to root site when GamiPress is active network wide
82 + *
83 + * @since 1.4.0
84 + *
85 + * @param string $request
86 + * @param WP_Query $wp_query
87 + *
88 + * @return string
89 + */
90 +function gamipress_network_wide_post_request( $request, $wp_query ) {
91 +
92 + global $wpdb;
93 +
94 + // If GamiPress is active network wide and we are not in main site, then filter all queries to our post types
95 + if(
96 + gamipress_is_network_wide_active()
97 + && ! is_main_site()
98 + && isset( $wp_query->query_vars['post_type'] )
99 + ) {
100 +
101 + $post_type = $wp_query->query_vars['post_type'];
102 +
103 + if( is_array( $post_type ) ) {
104 + $post_type = $post_type[0];
105 + }
106 +
107 + if(
108 + in_array( $post_type, array( 'points-type', 'achievement-type', 'rank-type' ) )
109 + || in_array( $post_type, gamipress_get_requirement_types_slugs() )
110 + || in_array( $post_type, gamipress_get_achievement_types_slugs() )
111 + || in_array( $post_type, gamipress_get_rank_types_slugs() )
112 + ) {
113 +
114 + // Replace {prefix}{site}posts to {prefix}posts
115 + $request = str_replace( $wpdb->posts, "{$wpdb->base_prefix}posts", $request );
116 +
117 + // Replace {prefix}{site}postmeta to {prefix}postmeta
118 + $request = str_replace( $wpdb->postmeta, "{$wpdb->base_prefix}postmeta", $request );
119 +
120 + }
121 +
122 + }
123 +
124 + return $request;
125 +
126 +}
127 +add_filter( 'posts_request', 'gamipress_network_wide_post_request', 10, 2 );
128 +
129 +/**
130 + * Check if GamiPress is network wide active
131 + *
132 + * @since 1.4.0
133 + *
134 + * @return bool
135 + */
136 +function gamipress_is_network_wide_active() {
137 +
138 + // Available filter to disable network data centralization
139 + if( apply_filters( 'gamipress_disable_network_data_centralization', false ) ) {
140 + GamiPress()->network_wide_active = false;
141 + return false;
142 + }
143 +
144 + if( GamiPress()->network_wide_active === null ) {
145 +
146 + if( ! is_multisite() ) {
147 +
148 + // Set to false if not is a multisite install
149 + GamiPress()->network_wide_active = false;
150 +
151 + } else {
152 +
153 + // Normally the is_plugin_active_for_network() function is only available in the admin area
154 + if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
155 + require_once ABSPATH . '/wp-admin/includes/plugin.php';
156 + }
157 +
158 + GamiPress()->network_wide_active = is_plugin_active_for_network( 'gamipress/gamipress.php' );
159 + }
160 +
161 + }
162 +
163 + return GamiPress()->network_wide_active;
164 +
165 +}
166 +
167 +/**
168 + * Check if a plugin is active on any site of network
169 + *
170 + * @since 1.4.8
171 + *
172 + * @param string $plugin Path to the main plugin file from plugins directory.
173 + *
174 + * @return bool
175 + */
176 +function gamipress_is_plugin_active_on_network( $plugin ) {
177 +
178 + $active_sites = gamipress_get_plugin_active_sites( $plugin );
179 +
180 + return ! empty( $active_sites );
181 +
182 +}
183 +
184 +/**
185 + * Get all sites a plugin is active
186 + *
187 + * @since 1.4.8
188 + *
189 + * @param string $plugin Path to the main plugin file from plugins directory.
190 + *
191 + * @return array
192 + */
193 +function gamipress_get_plugin_active_sites( $plugin ) {
194 +
195 + // Bail if not is a multisite install
196 + if( ! is_multisite() ) {
197 + return array( get_current_blog_id() );
198 + }
199 +
200 + // If plugin is active network wide, return all sites
201 + if( is_plugin_active_for_network( $plugin ) ) {
202 + return gamipress_get_network_site_ids();
203 + }
204 +
205 + $sites_active = array();
206 +
207 + // Store a copy of the original ID for later
208 + $blog_id = get_current_blog_id();
209 +
210 + // Loop through all sites
211 + foreach( gamipress_get_network_site_ids() as $site_blog_id ) {
212 +
213 + // Get active plugins in this site and check if plugin is active
214 + $active_plugins = gamipress_get_active_plugins_in_site( $site_blog_id );
215 +
216 + if( in_array( $plugin, $active_plugins, true ) ) {
217 + $sites_active[] = $site_blog_id;
218 + }
219 +
220 + }
221 +
222 + // Restore the original blog so the sky doesn't fall
223 + if ( $blog_id != get_current_blog_id() && is_multisite() ) {
224 + restore_current_blog();
225 + }
226 +
227 + return $sites_active;
228 +
229 +}
230 +
231 +/**
232 + * Get active plugins in a site (used to cache results)
233 + *
234 + * @since 1.4.8
235 + *
236 + * @param int $site_blog_id Site ID.
237 + *
238 + * @return array
239 + */
240 +function gamipress_get_active_plugins_in_site( $site_blog_id = null ) {
241 +
242 + if( $site_blog_id === null ) {
243 + $site_blog_id = get_current_blog_id();
244 + }
245 +
246 + $cache = gamipress_get_cache( 'gamipress_active_plugins', array(), false );
247 +
248 + if( ! is_array( $cache ) ) {
249 + $cache = array();
250 + }
251 +
252 + // If result already cached, return it
253 + if( isset( $cache[$site_blog_id] ) ) {
254 + return $cache[$site_blog_id];
255 + }
256 +
257 + // Store a copy of the original ID for later
258 + $blog_id = get_current_blog_id();
259 +
260 + // If we're polling a different blog, switch to it
261 + if ( $blog_id != $site_blog_id ) {
262 + switch_to_blog( $site_blog_id );
263 + }
264 +
265 + // Get active plugins in this site
266 + $cache[$site_blog_id] = (array) get_option( 'active_plugins', array() );
267 +
268 + // Restore the original blog
269 + if ( $blog_id != $site_blog_id && is_multisite() ) {
270 + restore_current_blog();
271 + }
272 +
273 + gamipress_set_cache( 'gamipress_active_plugins', $cache );
274 +
275 + return $cache[$site_blog_id];
276 +
277 +}
278 +
279 +/**
280 + * On save settings, also update GamiPress site option to make it network wide accessible
281 + *
282 + * @since 1.4.0
283 + *
284 + * @param string $override
285 + * @param mixed $options
286 + * @param CMB2 $cmb
287 + *
288 + * @return mixed
289 + */
290 +function gamipress_save_network_settings( $override, $options, $cmb ) {
291 +
292 + if( gamipress_is_network_wide_active() ) {
293 + // Set options as network option
294 + update_site_option( 'gamipress_settings', $options );
295 + }
296 +
297 + return $override;
298 +
299 +}
300 +add_action( 'cmb2_override_option_save_gamipress_settings', 'gamipress_save_network_settings', 10, 3 );
301 +
302 +/**
303 + * Filter the post edit link to return edit link from main site
304 + *
305 + * @since 1.4.0
306 + *
307 + * @param string $link The edit link.
308 + * @param int $post_id Post ID.
309 + * @param string $context The link context. If set to 'display' then ampersands are encoded.
310 + *
311 + * @return string
312 + */
313 +function gamipress_main_site_edit_post_link( $link, $post_id, $context ) {
314 +
315 + if( ! gamipress_is_network_wide_active() || is_main_site() ) {
316 + return $link;
317 + }
318 +
319 + // Try to get the post type of current site
320 + $post_type = get_post_type( $post_id );
321 +
322 + if( ! $post_type ) {
323 + // If this post not exists on current site, then get his post type from main site
324 + $post_type = gamipress_get_post_type( $post_id );
325 + }
326 +
327 + if(
328 + in_array( $post_type, array( 'points-type', 'achievement-type', 'rank-type' ) )
329 + || in_array( $post_type, gamipress_get_requirement_types_slugs() )
330 + || in_array( $post_type, gamipress_get_achievement_types_slugs() )
331 + || in_array( $post_type, gamipress_get_rank_types_slugs() )
332 + ) {
333 +
334 + $post_type_object = get_post_type_object( $post_type );
335 +
336 + if ( 'display' == $context )
337 + $action = '&amp;action=edit';
338 + else
339 + $action = '&action=edit';
340 +
341 + $link = get_admin_url( get_main_site_id(), sprintf( $post_type_object->_edit_link . $action, $post_id ) );
342 + }
343 +
344 + return $link;
345 +
346 +}
347 +add_filter( 'get_edit_post_link', 'gamipress_main_site_edit_post_link', 10, 3 );
348 +
349 +/**
350 + * Override CMB2 can save function to avoid issues on multisite installs
351 + *
352 + * @since 1.4.9
353 + *
354 + * @param bool $can_save
355 + * @param object $cmb
356 + *
357 + * @return bool
358 + */
359 +function gamipress_network_can_save_meta_boxes( $can_save, $cmb ) {
360 +
361 + global $post;
362 +
363 + if( is_multisite() && $post ) {
364 +
365 + // Custom can save check
366 + $can_save = (
367 + $cmb->prop( 'save_fields' )
368 + // check nonce
369 + && isset( $_POST[ $cmb->nonce() ] )
370 + && wp_verify_nonce( $_POST[ $cmb->nonce() ], $cmb->nonce() )
371 + // check if autosave
372 + && ! ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
373 + // get the metabox types & compare it to this type
374 + && ( in_array( $post->post_type, $cmb->box_types() ) )
375 + // Don't do updates during a switch-to-blog instance.
376 + //&& ! ( is_multisite() && ms_is_switched() ) // Removed, ms_is_switched() always returns true
377 + );
378 +
379 + }
380 +
381 + return $can_save;
382 +
383 +}
384 +add_filter( 'cmb2_can_save', 'gamipress_network_can_save_meta_boxes', 10, 2 );
385 +
386 +/**
387 + * Force to clean switched sites global to avoid issues with other plugins (since wp_restore_blog() doesn't cleans it)
388 + *
389 + * @since 1.5.7
390 + */
391 +function gamipress_fix_network_wp_insert_post() {
392 +
393 + if ( is_multisite() && ms_is_switched() ) {
394 + // Force to clean switched sites global
395 + $GLOBALS['_wp_switched_stack'] = array();
396 + }
397 +
398 +}
399 +add_action( 'wp_insert_post', 'gamipress_fix_network_wp_insert_post', 9 );
400 +
401 +/**
402 + * Switch to main site
403 + *
404 + * @since 1.6.3
405 + * @updated 2.1.0 Update the $gamipress_original_blog_id global var
406 + *
407 + * @return int The blog ID before switch to main site
408 + */
409 +function gamipress_switch_to_main_site() {
410 +
411 + global $gamipress_original_blog_id;
412 +
413 + $gamipress_original_blog_id = get_current_blog_id();
414 +
415 + // Switch to main site if not already on main site
416 + if( ! is_main_site() ) {
417 + switch_to_blog( get_main_site_id() );
418 + }
419 +
420 + return $gamipress_original_blog_id;
421 +
422 +}
423 +
424 +/**
425 + * Switch to main site just if GamiPress is network wide active
426 + *
427 + * @since 1.6.3
428 + *
429 + * @return int The blog ID before switch to main site
430 + */
431 +function gamipress_switch_to_main_site_if_network_wide_active() {
432 +
433 + // Switch to main site if GamiPress is network wide active
434 + if( gamipress_is_network_wide_active() ) {
435 + return gamipress_switch_to_main_site();
436 + }
437 +
438 + return get_current_blog_id();
439 +
440 +}
441 +
442 +/**
443 + * Get the original site ID even if GamiPress has switched to main site
444 + *
445 + * @since 2.1.0
446 + *
447 + * @return int The blog ID before switch to main site
448 + */
449 +function gamipress_get_original_site_id() {
450 +
451 + global $gamipress_original_blog_id;
452 +
453 + return ( $gamipress_original_blog_id ? $gamipress_original_blog_id : get_current_blog_id() );
454 +
455 +}