├── README.md
├── bp-multiblog-mode.php
├── includes
├── actions.php
├── admin.php
├── functions.php
├── index.php
├── settings.php
└── sub-actions.php
├── index.php
└── readme.txt
/README.md:
--------------------------------------------------------------------------------
1 | # BP Multiblog Mode #
2 |
3 | Enable and customize BuddyPress on other sites in your network than the root blog.
4 |
5 | ## Description ##
6 |
7 | > This WordPress plugin requires at least [WordPress](https://wordpress.org) 4.6 and [BuddyPress](https://buddypress.org) 2.7.
8 |
9 | Run BuddyPress on your network subsites, but not all of them. Instead of defining the BP_ENABLE_MULTIBLOG constant, with this plugin you can choose on which sites BuddyPress acts as if BP_ENABLE_MULTIBLOG was defined.
10 |
11 | In addition, this plugin allows you to:
12 |
13 | * Limit the BuddyPress implementation to site members
14 | * Limit Activity Stream items to those belonging to the current site
15 | * Define Extended Profile field groups per site
16 | * Use BuddyPress avatars and/or other file uploads from the current site
17 |
18 | Note that you need to have BuddyPress network-activated in your Multisite installation for this plugin to work.
19 |
20 | ## Installation ##
21 |
22 | If you download BP Multiblog Mode manually, make sure it is uploaded to "/wp-content/plugins/bp-multiblog-mode/".
23 |
24 | Activate BP Multiblog Mode in the "Plugins" network admin panel using the "Network Activate" link. You need to use WordPress Multisite, for this plugin to work. Additionally, you need to have BuddyPress network-activated in you Multisite installation, and not have defined the `BP_ENABLE_MULTIBLOG` constant manually.
25 |
26 | ## Updates ##
27 |
28 | This plugin is not hosted in the official WordPress repository. Instead, updating is supported through use of the [GitHub Updater](https://github.com/afragen/github-updater/) plugin by @afragen and friends.
29 |
30 | ## Contribution ##
31 |
32 | You can contribute to the development of this plugin by [opening a new issue](https://github.com/lmoffereins/bp-multiblog-mode/issues/) to report a bug or request a feature in the plugin's GitHub repository.
--------------------------------------------------------------------------------
/bp-multiblog-mode.php:
--------------------------------------------------------------------------------
1 | setup_globals();
51 | $instance->includes();
52 | $instance->setup_actions();
53 | }
54 |
55 | return $instance;
56 | }
57 |
58 | /**
59 | * Prevent the plugin class from being loaded more than once
60 | */
61 | private function __construct() { /* Nothing to do */ }
62 |
63 | /** Private methods *************************************************/
64 |
65 | /**
66 | * Setup default class globals
67 | *
68 | * @since 1.0.0
69 | */
70 | private function setup_globals() {
71 |
72 | /** Versions **********************************************************/
73 |
74 | $this->version = '1.0.0';
75 |
76 | /** Paths *************************************************************/
77 |
78 | // Setup some base path and URL information
79 | $this->file = __FILE__;
80 | $this->basename = plugin_basename( $this->file );
81 | $this->plugin_dir = plugin_dir_path( $this->file );
82 | $this->plugin_url = plugin_dir_url ( $this->file );
83 |
84 | // Includes
85 | $this->includes_dir = trailingslashit( $this->plugin_dir . 'includes' );
86 | $this->includes_url = trailingslashit( $this->plugin_url . 'includes' );
87 |
88 | // Languages
89 | $this->lang_dir = trailingslashit( $this->plugin_dir . 'languages' );
90 |
91 | /** Identifiers *******************************************************/
92 |
93 | $this->root_blog_id = defined( 'BP_ROOT_BLOG' ) ? (int) BP_ROOT_BLOG : get_network()->site_id;
94 |
95 | /** Misc **************************************************************/
96 |
97 | $this->extend = new stdClass();
98 | $this->domain = 'bp-multiblog-mode';
99 | }
100 |
101 | /**
102 | * Include the required files
103 | *
104 | * @since 1.0.0
105 | */
106 | private function includes() {
107 |
108 | // Core
109 | require( $this->includes_dir . 'functions.php' );
110 | require( $this->includes_dir . 'sub-actions.php' );
111 |
112 | // Admin
113 | if ( is_admin() ) {
114 | require( $this->includes_dir . 'admin.php' );
115 | require( $this->includes_dir . 'settings.php' );
116 | }
117 |
118 | // Hooks
119 | if ( $this->can_multiblog() ) {
120 | require( $this->includes_dir . 'actions.php' );
121 | }
122 | }
123 |
124 | /**
125 | * Setup default actions and filters
126 | *
127 | * @since 1.0.0
128 | */
129 | private function setup_actions() {
130 |
131 | // Add actions to plugin activation and deactivation hooks
132 | add_action( 'activate_' . $this->basename, 'bp_multiblog_mode_activation' );
133 | add_action( 'deactivate_' . $this->basename, 'bp_multiblog_mode_deactivation' );
134 |
135 | // Load textdomain
136 | add_action( 'plugins_loaded', array( $this, 'load_textdomain' ), 20 );
137 |
138 | // Do Multiblog for the enabled site
139 | if ( $this->can_multiblog() && bp_multiblog_mode_is_enabled() ) {
140 | add_filter( 'bp_get_root_blog_id', 'get_current_blog_id' );
141 | add_filter( 'bp_is_multiblog_mode', '__return_true' );
142 |
143 | // Reset actual root blog where necessary
144 | add_filter( 'bp_get_taxonomy_term_site_id', array( $this, 'taxonomy_term_site_id' ), 1 );
145 | }
146 | }
147 |
148 | /** Plugin **********************************************************/
149 |
150 | /**
151 | * Return whether the plugin logic can be run
152 | *
153 | * Checks whether:
154 | * - BP is network activated
155 | * - BP_ENABLE_MULTIBLOG is not enabled through the constant
156 | * - there are multiple sites in the network
157 | *
158 | * @since 1.0.0
159 | *
160 | * @return bool Can we do Multiblog?
161 | */
162 | public function can_multiblog() {
163 | return bp_is_network_activated() && ! ( defined( 'BP_ENABLE_MULTIBLOG' ) && BP_ENABLE_MULTIBLOG ) && (int) get_blog_count() > 1;
164 | }
165 |
166 | /**
167 | * Load the translation file for current language. Checks the languages
168 | * folder inside the plugin first, and then the default WordPress
169 | * languages folder.
170 | *
171 | * Note that custom translation files inside the plugin folder will be
172 | * removed on plugin updates. If you're creating custom translation
173 | * files, please use the global language folder.
174 | *
175 | * @since 1.0.0
176 | *
177 | * @uses apply_filters() Calls 'plugin_locale' with {@link get_locale()} value
178 | * @uses load_textdomain() To load the textdomain
179 | * @uses load_plugin_textdomain() To load the textdomain
180 | */
181 | public function load_textdomain() {
182 |
183 | // Traditional WordPress plugin locale filter
184 | $locale = apply_filters( 'plugin_locale', get_locale(), $this->domain );
185 | $mofile = sprintf( '%1$s-%2$s.mo', $this->domain, $locale );
186 |
187 | // Setup paths to current locale file
188 | $mofile_local = $this->lang_dir . $mofile;
189 | $mofile_global = WP_LANG_DIR . '/bp-multiblog-mode/' . $mofile;
190 |
191 | // Look in global /wp-content/languages/bp-multiblog-mode folder
192 | load_textdomain( $this->domain, $mofile_global );
193 |
194 | // Look in local /wp-content/plugins/bp-multiblog-mode/languages/ folder
195 | load_textdomain( $this->domain, $mofile_local );
196 |
197 | // Look in global /wp-content/languages/plugins/
198 | load_plugin_textdomain( $this->domain );
199 | }
200 |
201 | /** Public methods **************************************************/
202 |
203 | /**
204 | * Modify the site ID where the taxonomy terms live
205 | *
206 | * @since 1.0.0
207 | *
208 | * @param int $site_id Site ID
209 | * @return int Site ID
210 | */
211 | public function taxonomy_term_site_id( $site_id ) {
212 |
213 | // Use the root's registered taxonomy terms
214 | if ( bp_multiblog_mode_use_root_taxonomy_terms() ) {
215 | $site_id = bp_multiblog_mode_get_root_blog_id();
216 | }
217 |
218 | return $site_id;
219 | }
220 | }
221 |
222 | /**
223 | * Return single instance of this main plugin class
224 | *
225 | * @since 1.0.0
226 | *
227 | * @return BP Multiblog Mode class
228 | */
229 | function bp_multiblog_mode() {
230 | return BP_Multiblog_Mode::instance();
231 | }
232 |
233 | // Initiate plugin on bp_after_setup_actions. Only on Multisite
234 | if ( is_multisite() ) {
235 | add_action( 'bp_after_setup_actions', 'bp_multiblog_mode' );
236 | }
237 |
238 | endif; // class_exists
239 |
--------------------------------------------------------------------------------
/includes/actions.php:
--------------------------------------------------------------------------------
1 | setup_globals();
28 | $this->setup_actions();
29 | }
30 |
31 | /**
32 | * Define default class globals
33 | *
34 | * @since 1.0.0
35 | */
36 | private function setup_globals() {
37 | $this->parent_page = bp_core_do_network_admin() ? 'settings.php' : 'options-general.php';
38 | $this->settings_page = is_network_admin() ? 'bp-multiblog-mode-network' : 'bp-multiblog-mode';
39 | $this->minimum_capability = bp_core_do_network_admin() ? 'manage_network_options' : 'manage_options';
40 | $this->plugin_screen_id = 'settings_page_' . $this->settings_page;
41 | }
42 |
43 | /**
44 | * Define default actions and filters
45 | *
46 | * @since 1.0.0
47 | */
48 | private function setup_actions() {
49 |
50 | // For backcompat, consider admin hook
51 | $admin_menus_hook = function_exists( 'bp_core_get_admin_settings_tabs' ) ? 'bp_admin_submenu_pages' : bp_core_admin_hook();
52 |
53 | // Admin page
54 | add_action( $admin_menus_hook, array( $this, 'admin_menus' ) );
55 | add_filter( 'bp_admin_head', array( $this, 'admin_head' ), 999 );
56 | add_filter( 'bp_core_get_admin_settings_tabs', array( $this, 'admin_tabs' ) );
57 | add_filter( 'bp_core_get_admin_tabs', array( $this, 'admin_tabs' ), 10, 2 );
58 |
59 | // Styling
60 | add_action( 'bp_admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
61 |
62 | // Settings
63 | add_action( 'bp_admin_init', array( $this, 'register_settings' ) );
64 | add_filter( 'bp_map_meta_caps', array( $this, 'map_settings_meta_caps' ), 10, 4 );
65 |
66 | // XProfile
67 | add_action( 'xprofile_group_after_submitbox', array( $this, 'xprofile_group_sites_metabox' ) );
68 | add_action( 'xprofile_group_after_save', array( $this, 'xprofile_save_group_sites' ) );
69 | add_action( 'xprofile_admin_group_action', array( $this, 'xprofile_group_admin_label' ) );
70 | }
71 |
72 | /** Admin Page ******************************************************/
73 |
74 | /**
75 | * Register network admin menu elements
76 | *
77 | * @since 1.0.0
78 | *
79 | * @param array $submenu_pages The BP_Admin submenu pages passed by reference
80 | */
81 | public function admin_menus( &$submenu_pages = array() ) {
82 |
83 | // Bail when user cannot manage
84 | if ( ! bp_current_user_can( $this->minimum_capability ) )
85 | return;
86 |
87 | // Bail when the page has no settings
88 | if ( ! bp_multiblog_mode_admin_page_has_settings( $this->settings_page ) )
89 | return;
90 |
91 | $hooks = array();
92 |
93 | // Core settings page
94 | $settings_page = add_submenu_page(
95 | $this->parent_page,
96 | esc_html__( 'BuddyPress Multiblog', 'bp-multiblog-mode' ),
97 | esc_html__( 'Multiblog', 'bp-multiblog-mode' ),
98 | $this->minimum_capability,
99 | 'bp-multiblog-mode',
100 | 'bp_multiblog_mode_admin_settings_page'
101 | );
102 |
103 | $hooks[] = $settings_page;
104 |
105 | // Blend in BP's administration
106 | foreach ( $hooks as $hook ) {
107 | add_action( "admin_head-{$hook}", 'bp_core_modify_admin_menu_highlight' );
108 | }
109 |
110 | // Add to navigation tabs
111 | if ( isset( $submenu_pages['settings'] ) ) {
112 | $submenu_pages['settings']['bp-multiblog-mode'] = $settings_page;
113 | }
114 | }
115 |
116 | /**
117 | * Hide the plugin page from the admin menu
118 | *
119 | * @see BP_Admin::admin_head()
120 | *
121 | * @since 1.0.0
122 | */
123 | public function admin_head() {
124 | remove_submenu_page( $this->parent_page, 'bp-multiblog-mode' );
125 | }
126 |
127 | /**
128 | * Modify the admin tabs of BP's admin page
129 | *
130 | * @since 1.0.0
131 | *
132 | * @param array $tabs Page tags
133 | * @param string $context Tabs context. Defaults to 'settings' for backcompat
134 | * @return array Page tabs
135 | */
136 | public function admin_tabs( $tabs, $context = 'settings' ) {
137 |
138 | // Prepare tabs
139 | $settings_tabs = array();
140 | $tools_tabs = array();
141 |
142 | // Append Multiblog Mode page tab, when settings are registered
143 | if ( bp_multiblog_mode_admin_page_has_settings( $this->settings_page ) ) {
144 | $settings_tabs[] = array(
145 | 'id' => 'bp-multiblog-mode',
146 | 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-multiblog-mode' ), 'admin.php' ) ),
147 | 'name' => esc_html__( 'Multiblog', 'bp-multiblog-mode' ),
148 | );
149 | }
150 |
151 | // Add settings tabs
152 | if ( 'settings' === $context ) {
153 | foreach ( $settings_tabs as $tab ) {
154 |
155 | // For backcompat, only add tab once
156 | if ( ! isset( $tabs[ $tab['id'] ] ) ) {
157 | $tabs[ $tab['id'] ] = $tab;
158 | }
159 | }
160 |
161 | // Add tools tabs
162 | } else if ( 'tools' === $context ) {
163 | foreach ( $tools_tabs as $tab ) {
164 |
165 | // For backcompat, only add tab once
166 | if ( ! isset( $tabs[ $tab['id'] ] ) ) {
167 | $tabs[ $tab['id'] ] = $tab;
168 | }
169 | }
170 | }
171 |
172 | return $tabs;
173 | }
174 |
175 | /** Styling *********************************************************/
176 |
177 | /**
178 | * Add general styling to the admin area
179 | *
180 | * @since 1.0.0
181 | */
182 | public function enqueue_scripts() {
183 |
184 | // Define local variable(s)
185 | $styles = array();
186 | $screen = get_current_screen();
187 | $network = is_network_admin() ? '-network' : '';
188 |
189 | // Network admin page
190 | if ( $screen->id === $this->plugin_screen_id ) {
191 |
192 | // Mimic post inline-edit styles for .cat-checklist
193 | $styles[] = '.form-table .widefat th, .form-table .widefat td { padding: 8px 10px; font-weight: normal; }';
194 | $styles[] = '.form-table .widefat .check-column { width: 2.2em; }';
195 | $styles[] = '.form-table p + .cat-checklist { margin-top: 6px; }';
196 | $styles[] = '.form-table .widefat .column-blogname strong { display: block; margin-bottom: .2em; font-size: 14px; }';
197 | $styles[] = '.form-table .widefat .column-blogname strong ~ span { font-size: 13px; font-style: italic; line-height: 1.5em; }';
198 |
199 | // Small screens
200 | $styles[] = '@media screen and (max-width: 782px) {';
201 | $styles[] = '.form-table .widefat th, .form-table .widefat td { display: table-cell; }';
202 | $styles[] = '}';
203 |
204 | // BP XProfile admin page
205 | } elseif ( "users_page_bp-profile-setup{$network}" === $screen->id ) {
206 |
207 | // Group detail
208 | $styles[] = '.wp-core-ui .tab-toolbar .button.group-sites { color: #555 !important; }';
209 | $styles[] = '.wp-core-ui .tab-toolbar .button.group-sites-error { color: #f00 !important; border-color: #f00 !important; }';
210 |
211 | // Add/edit group
212 | if ( isset( $_GET['mode'] ) && in_array( $_GET['mode'], array( 'add_group', 'edit_group' ) ) ) {
213 |
214 | // Sites metabox
215 | $styles[] = '#bp-multiblog-mode_sitediv label { margin: .5em 0; display: block; }';
216 | $styles[] = '#bp-multiblog-mode_sitediv label .description { padding-left: 25px; display: block; opacity: .7; }';
217 |
218 | // Small screens
219 | $styles[] = '@media screen and (max-width: 782px) {';
220 | $styles[] = '#bp-multiblog-mode_sitediv label { max-width: none; float: none; margin: 1em 0; font-size: 16px; }';
221 | $styles[] = '#bp-multiblog-mode_sitediv label .description { padding: 0 0 0 34px; }';
222 | $styles[] = '}';
223 | }
224 | }
225 |
226 | if ( ! empty( $styles ) ) {
227 | wp_add_inline_style( 'bp-admin-common-css', implode( "\n", $styles ) );
228 | }
229 | }
230 |
231 | /** Settings ********************************************************/
232 |
233 | /**
234 | * Register plugin settings
235 | *
236 | * @since 1.0.0
237 | */
238 | public function register_settings() {
239 |
240 | // Bail if no sections available
241 | $sections = bp_multiblog_mode_admin_get_settings_sections();
242 | if ( empty( $sections ) )
243 | return false;
244 |
245 | // Loop through sections
246 | foreach ( (array) $sections as $section_id => $section ) {
247 |
248 | // Only proceed if current user can see this section
249 | if ( ! current_user_can( $section_id ) )
250 | continue;
251 |
252 | // Only add section and fields if section has fields
253 | $fields = bp_multiblog_mode_admin_get_settings_fields_for_section( $section_id );
254 | if ( empty( $fields ) )
255 | continue;
256 |
257 | // Define section page
258 | if ( ! empty( $section['page'] ) ) {
259 | $page = $section['page'];
260 | } else {
261 | $page = 'bp-multiblog-mode';
262 | }
263 |
264 | // Add the section
265 | add_settings_section( $section_id, $section['title'], $section['callback'], $page );
266 |
267 | // Loop through fields for this section
268 | foreach ( (array) $fields as $field_id => $field ) {
269 |
270 | // Add the field
271 | if ( ! empty( $field['callback'] ) && ! empty( $field['title'] ) ) {
272 | add_settings_field( $field_id, $field['title'], $field['callback'], $page, $section_id, $field['args'] );
273 | }
274 |
275 | // Register the setting
276 | if ( ! empty( $field['sanitize_callback'] ) ) {
277 | register_setting( $page, $field_id, $field['sanitize_callback'] );
278 | }
279 | }
280 | }
281 | }
282 |
283 | /**
284 | * Map caps for the plugin settings
285 | *
286 | * @since 1.0.0
287 | *
288 | * @param array $caps Mapped caps
289 | * @param string $cap Required capability name
290 | * @param int $user_id User ID
291 | * @param array $args Additional arguments
292 | * @return array Mapped caps
293 | */
294 | public function map_settings_meta_caps( $caps = array(), $cap = '', $user_id = 0, $args = array() ) {
295 |
296 | // Check the required capability
297 | switch ( $cap ) {
298 |
299 | // Settings
300 | case 'bp_multiblog_mode_settings_general_network' :
301 | case 'bp_multiblog_mode_settings_general' :
302 | $caps = array( $this->minimum_capability );
303 | break;
304 | }
305 |
306 | return $caps;
307 | }
308 |
309 | /** XProfile ********************************************************/
310 |
311 | /**
312 | * Add XProfile field group Sites metabox
313 | *
314 | * @since 1.0.0
315 | *
316 | * @param BP_XProfile_Group $group
317 | */
318 | public function xprofile_group_sites_metabox( $group ) {
319 |
320 | // The primary field group is for all, so bail
321 | if ( 1 === (int) $group->id )
322 | return;
323 |
324 | // Bail when no sites are Multiblog enabled
325 | if ( ! $sites = bp_multiblog_mode_get_enabled_sites() )
326 | return;
327 |
328 | // Prepend the root site
329 | array_unshift( $sites, get_site( bp_multiblog_mode_get_root_blog_id() ) );
330 |
331 | // Get the group's sites
332 | $group_sites = bp_multiblog_mode_xprofile_get_group_sites( $group->id );
333 |
334 | ?>
335 |
336 |
337 |
338 |
339 |
340 |
341 |
357 |
358 |
359 |
360 |
361 |
362 |
363 | id, 'group', 'multiblog_site' );
388 |
389 | /*
390 | * We interpret an empty array as disassociating the group from all sites. This is
391 | * represented internally with the '_none' flag.
392 | */
393 | if ( empty( $group_sites ) ) {
394 | bp_xprofile_add_meta( $group->id, 'group', 'multiblog_site', '_none' );
395 | }
396 |
397 | /*
398 | * Unrestricted groups are represented in the database as having no 'multiblog_site'.
399 | * We detect whether a group is being set to unrestricted by checking whether the
400 | * list of sites passed to the method is the same as the list of available sites,
401 | * plus the root blog.
402 | */
403 | $sites = bp_multiblog_mode_get_enabled_sites( array( 'fields' => 'ids' ) );
404 | $sites[] = bp_multiblog_mode_get_root_blog_id();
405 |
406 | sort( $group_sites );
407 | sort( $sites );
408 |
409 | // Only save if this is a restricted group
410 | if ( $sites !== $group_sites ) {
411 | // Save new sites.
412 | foreach ( $group_sites as $site_id ) {
413 | bp_xprofile_add_meta( $group->id, 'group', 'multiblog_site', $site_id );
414 | }
415 | }
416 | }
417 |
418 | /**
419 | * Display a label representing the XProfile group's sites
420 | *
421 | * @since 1.0.0
422 | *
423 | * @param BP_XProfile_Group $group
424 | */
425 | public function xprofile_group_admin_label( $group ) {
426 |
427 | // The primary field group is for all, so bail
428 | if ( 1 === (int) $group->id )
429 | return;
430 |
431 | // Get all sites and the group's sites
432 | $sites = bp_multiblog_mode_get_enabled_sites( array( 'fields' => 'ids' ) );
433 | $sites[] = bp_multiblog_mode_get_root_blog_id();
434 | $group_sites = bp_multiblog_mode_xprofile_get_group_sites( $group->id );
435 |
436 | // Bail when the group applies to all sites
437 | if ( array_values( $sites ) == $group_sites )
438 | return;
439 |
440 | $label = '';
441 | if ( ! empty( $group_sites ) ) {
442 | $count = count( $group_sites );
443 |
444 | if ( 1 === $count ) {
445 | $site_id = reset( $group_sites );
446 | $label_text = sprintf( esc_html__( 'Site: %s', 'bp-multiblog-mode' ), get_blog_option( $site_id, 'blogname' ) );
447 | } else {
448 | $label_text = sprintf( esc_html__( 'For %d Sites', 'bp-multiblog-mode' ), $count );
449 | }
450 |
451 | $label = '' . $label_text . '
';
452 | } else {
453 | $label = '' . esc_html__( 'Unavailable to all sites', 'bp-multiblog-mode' ) . '
';
454 | }
455 |
456 | echo $label;
457 | }
458 | }
459 |
460 | /**
461 | * Setup the extension logic for BuddyPress
462 | *
463 | * @since 1.0.0
464 | *
465 | * @uses BP_Multiblog_Mode_Admin
466 | */
467 | function bp_multiblog_mode_admin() {
468 | bp_multiblog_mode()->admin = new BP_Multiblog_Mode_Admin;
469 | }
470 |
471 | endif; // class_exists
472 |
--------------------------------------------------------------------------------
/includes/functions.php:
--------------------------------------------------------------------------------
1 | root_blog_id;
22 | }
23 |
24 | /**
25 | * Return whether the given site is the actual BP root blog
26 | *
27 | * @since 1.0.0
28 | *
29 | * @param int $site_id Optional. Site id. Defaults to the current site id.
30 | * @return bool Is this the actual BP root blog?
31 | */
32 | function bp_multiblog_mode_is_root_blog( $site_id = 0 ) {
33 |
34 | // Default to the current site
35 | if ( empty( $site_id ) ) {
36 | $site_id = get_current_blog_id();
37 | }
38 |
39 | // Define return value
40 | $retval = false;
41 |
42 | // Check the actual root blog ID
43 | if ( bp_multiblog_mode_get_root_blog_id() === (int) $site_id ) {
44 | $retval = true;
45 | }
46 |
47 | return $retval;
48 | }
49 |
50 | /**
51 | * Return whether the given site has Multiblog mode enabled
52 | *
53 | * @since 1.0.0
54 | *
55 | * @uses apply_filters() Calls 'bp_multiblog_mode_is_enabled'
56 | *
57 | * @param int $site_id Optional. Site id. Defaults to the current site id.
58 | * @return bool Is Multiblog mode enabled?
59 | */
60 | function bp_multiblog_mode_is_enabled( $site_id = 0 ) {
61 |
62 | // Default to the current site
63 | if ( empty( $site_id ) ) {
64 | $site_id = get_current_blog_id();
65 | }
66 |
67 | // Define return value
68 | $is_enabled = false;
69 |
70 | // Check the site's setting when BP is network activated, but not for the real root blog
71 | if ( bp_is_network_activated() && ! bp_multiblog_mode_is_root_blog( $site_id ) ) {
72 | $is_enabled = (bool) get_blog_option( $site_id, '_bp_multiblog_mode_enabled', false );
73 | }
74 |
75 | /**
76 | * Filter whether Multiblog is enabled for the site
77 | *
78 | * @since 1.0.0
79 | *
80 | * @param bool $is_enabled Is Multiblog enabled
81 | * @param int $site_id Site id
82 | */
83 | return apply_filters( 'bp_multiblog_mode_is_enabled', $is_enabled, $site_id );
84 | }
85 |
86 | /**
87 | * Return the sites of the network
88 | *
89 | * @since 1.0.0
90 | *
91 | * @uses apply_filters() Calls 'bp_multiblog_mode_get_sites'
92 | *
93 | * @param array $query_args {
94 | * Optional. Query arguments for WP_Site_Query.
95 | *
96 | * @type bool $multiblog Whether to return only Multiblog enabled sites.
97 | * }
98 | * @return array Sites, maybe only enabled
99 | */
100 | function bp_multiblog_mode_get_sites( $query_args = array() ) {
101 |
102 | // Provide a fallback for non-array parameter
103 | if ( ! is_array( $query_args ) ) {
104 | $query_args = array( 'multiblog' => (bool) $query_args );
105 | }
106 |
107 | // Define query args
108 | $query_args = wp_parse_args( $query_args, array(
109 | 'network_id' => get_network()->id,
110 | 'multiblog' => false
111 | ) );
112 |
113 | // Query Multiblog-only?
114 | $multiblog = (bool) $query_args['multiblog'];
115 |
116 | // Get the Network's sites
117 | $sites = get_sites( $query_args );
118 |
119 | // Filter for Multiblog enabled sites
120 | if ( $multiblog ) {
121 | foreach ( $sites as $k => $site ) {
122 |
123 | // Remove the unenabled site
124 | if ( ! bp_multiblog_mode_is_enabled( is_a( $site, 'WP_Site' ) ? $site->id : (int) $site ) ) {
125 | unset( $sites[ $k ] );
126 | }
127 | }
128 | }
129 |
130 | /**
131 | * Filter the sites of the network
132 | *
133 | * @since 1.0.0
134 | *
135 | * @param array $sites Sites
136 | * @param array $query_args Query arguments for WP_Site_Query
137 | */
138 | return apply_filters( 'bp_multiblog_mode_get_sites', $sites, $query_args );
139 | }
140 |
141 | /**
142 | * Return the Multiblog enabled sites of the network
143 | *
144 | * @see bp_multiblog_mode_get_sites()
145 | *
146 | * @since 1.0.0
147 | *
148 | * @param array $query_args Optional. See {@see bp_multiblog_mode_get_sites()}.
149 | * @return array Multiblog enabled sites
150 | */
151 | function bp_multiblog_mode_get_enabled_sites( $query_args = array() ) {
152 |
153 | // Parse defaults
154 | $query_args = wp_parse_args( $query_args, array(
155 | 'multiblog' => true
156 | ) );
157 |
158 | return bp_multiblog_mode_get_sites( $query_args );
159 | }
160 |
161 | /**
162 | * Return whether the site uses the root's taxonomy terms
163 | *
164 | * @since 1.0.0
165 | *
166 | * @return bool Use root taxonomy terms
167 | */
168 | function bp_multiblog_mode_use_root_taxonomy_terms() {
169 | $use_root_taxonomy_terms = ! get_option( '_bp_multiblog_mode_taxonomy_terms', false );
170 |
171 | /**
172 | * Filter whether to use the root's taxonomy terms
173 | *
174 | * @since 1.0.0
175 | *
176 | * @param bool $use_root_taxonomy_terms Use the root's taxonomy terms
177 | */
178 | return (bool) apply_filters( 'bp_multiblog_mode_use_root_taxonomy_terms', $use_root_taxonomy_terms );
179 | }
180 |
181 | /**
182 | * Return the given site's user ids
183 | *
184 | * @since 1.0.0
185 | *
186 | * @uses apply_filters() Calls 'bp_multiblog_mode_get_site_users'
187 | *
188 | * @param int $site_id Optional. Site ID. Defaults to the current site.
189 | * @param array $query_args Optional. Additional query arguments for `WP_User_Query`.
190 | * @return array Site user ids
191 | */
192 | function bp_multiblog_mode_get_site_users( $site_id = 0, $query_args = array() ) {
193 |
194 | // Define user query args
195 | $query_args = wp_parse_args( $query_args, array( 'fields' => 'ids' ) );
196 |
197 | // Site id default is set in `WP_User_Query`
198 | if ( ! empty( $site_id ) ) {
199 | $query_args['blog_id'] = (int) $site_id;
200 | }
201 |
202 | $users = get_users( $query_args );
203 |
204 | /**
205 | * Filter the site's users
206 | *
207 | * @since 1.0.0
208 | *
209 | * @param array $users Site user ids
210 | * @param int $site_id Site id
211 | * @param array $query_args Arguments for `WP_User_Query`
212 | */
213 | return apply_filters( 'bp_multiblog_mode_get_site_users', $users, $site_id, $query_args );
214 | }
215 |
216 | /**
217 | * Return the given site's user count
218 | *
219 | * @since 1.0.0
220 | *
221 | * @param int $site_id Optional. Site ID. Defaults to the current site.
222 | * @param array $query_args Optional. Additional query arguments for `WP_User_Query`.
223 | * @return int Site user count
224 | */
225 | function bp_multiblog_mode_get_site_total_user_count( $site_id = 0, $query_args = array() ) {
226 |
227 | // Define user query args
228 | $query_args = wp_parse_args( $query_args, array( 'count_total' => true ) );
229 |
230 | // Site id default is set in `WP_User_Query`
231 | if ( ! empty( $site_id ) ) {
232 | $query_args['blog_id'] = (int) $site_id;
233 | }
234 |
235 | $user_search = new WP_User_Query( $query_args );
236 |
237 | return $user_search->get_results();
238 | }
239 |
240 | /** Members *************************************************************/
241 |
242 | /**
243 | * Return whether to limit BP content to site members
244 | *
245 | * @since 1.0.0
246 | *
247 | * @uses apply_filters() Calls 'bp_multiblog_mode_site_members'
248 | *
249 | * @return bool Limit content to site members
250 | */
251 | function bp_multiblog_mode_limit_site_members() {
252 | $site_members = get_option( '_bp_multiblog_mode_site_members', false );
253 |
254 | /**
255 | * Filter whether to limit BP content to site members
256 | *
257 | * @since 1.0.0
258 | *
259 | * @param bool $site_members Limit content to site members
260 | */
261 | return (bool) apply_filters( 'bp_multiblog_mode_site_members', $site_members );
262 | }
263 |
264 | /**
265 | * Block member profiles of non-site members
266 | *
267 | * @since 1.0.0
268 | *
269 | * @param string $member_slug Member slug
270 | * @return string Member slug
271 | */
272 | function bp_multiblog_mode_members_block_profile( $member_slug ) {
273 |
274 | // Block access to profiles of non-site members
275 | if ( bp_multiblog_mode_limit_site_members() ) {
276 |
277 | // Get the queried user
278 | $field = bp_is_username_compatibility_mode() ? 'login' : 'slug';
279 | $user = get_user_by( $field, $member_slug );
280 |
281 | // Get the site members
282 | $site_members = array_map( 'intval', bp_multiblog_mode_get_site_users() );
283 |
284 | // The queried user is not a site member
285 | if ( $user && ! in_array( $user->ID, $site_members, true ) ) {
286 |
287 | // Mock a non-existing user slug because a falsey value will result in
288 | // a failed page request unaccounted for in `bp_core_set_uri_globals()`
289 | $member_slug = '___BP_MULTIBLOG_MODE___';
290 | }
291 | }
292 |
293 | return $member_slug;
294 | }
295 |
296 | /**
297 | * Modify the members query SQL clauses
298 | *
299 | * @since 1.0.0
300 | *
301 | * @param array $sql SQL clauses
302 | * @param BP_User_Query $query Members query
303 | * @return array SQL clauses
304 | */
305 | function bp_multiblog_mode_members_limit_users( $sql, $query ) {
306 |
307 | // Force limit member query results to users of the current site
308 | if ( bp_multiblog_mode_limit_site_members() ) {
309 |
310 | // Get the site members
311 | $site_members = implode( ',', bp_multiblog_mode_get_site_users() );
312 |
313 | // The queried user(s) should be a site member
314 | $sql['where']['bp_multiblog_mode_limit_site_members'] = "u.{$query->uid_name} IN ({$site_members})";
315 | }
316 |
317 | return $sql;
318 | }
319 |
320 | /**
321 | * Modify the total site member count
322 | *
323 | * @see bp_core_get_total_member_count()
324 | *
325 | * @since 1.0.0
326 | *
327 | * @param int $count Site member count
328 | * @return int Site member count
329 | */
330 | function bp_multiblog_mode_limit_total_member_count( $count ) {
331 | global $wpdb;
332 |
333 | // Recount total site member count
334 | if ( bp_multiblog_mode_limit_site_members() ) {
335 |
336 | // Get the site members
337 | $site_members = implode( ',', bp_multiblog_mode_get_site_users() );
338 |
339 | // The queried user(s) should be a site member
340 | $status_sql = bp_core_get_status_sql();
341 | $count = $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->users} WHERE {$status_sql} AND {$wpdb->users}.ID IN ({$site_members})" );
342 | }
343 |
344 | return $count;
345 | }
346 |
347 | /**
348 | * Modify the active site member count
349 | *
350 | * @see bp_core_get_active_member_count()
351 | *
352 | * @since 1.0.0
353 | *
354 | * @param int $count Site member count
355 | * @return int Site member count
356 | */
357 | function bp_multiblog_mode_limit_active_member_count( $count ) {
358 | global $wpdb;
359 |
360 | // Recount active site member count
361 | if ( bp_multiblog_mode_limit_site_members() ) {
362 | $bp = buddypress();
363 |
364 | // Get the site members
365 | $site_members = implode( ',', bp_multiblog_mode_get_site_users() );
366 |
367 | // Avoid a costly join by splitting the lookup.
368 | if ( is_multisite() ) {
369 | $sql = "SELECT ID FROM {$wpdb->users} WHERE (user_status != 0 OR deleted != 0 OR user_status != 0)";
370 | } else {
371 | $sql = "SELECT ID FROM {$wpdb->users} WHERE user_status != 0";
372 | }
373 |
374 | // The queried user(s) should be a site member
375 | $exclude_users = $wpdb->get_col( $sql );
376 | $exclude_users_sql = !empty( $exclude_users ) ? "AND user_id NOT IN (" . implode( ',', wp_parse_id_list( $exclude_users ) ) . ")" : '';
377 | $count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(user_id) FROM {$bp->members->table_name_last_activity} WHERE component = %s AND type = 'last_activity' {$exclude_users_sql} AND user_id IN ({$site_members})", $bp->members->id ) );
378 | }
379 |
380 | return $count;
381 | }
382 |
383 | /** Activity ************************************************************/
384 |
385 | /**
386 | * Return whether to limit the activity stream to site items
387 | *
388 | * This concerns activity items that are created in the context of the site.
389 | *
390 | * @since 1.0.0
391 | *
392 | * @return bool Limit activity items to the site
393 | */
394 | function bp_multiblog_mode_activity_limit_site_items() {
395 | $limit_site_items = get_option( '_bp_multiblog_mode_activity_stream', false );
396 |
397 | /**
398 | * Filter whether to limit the activity stream to site items
399 | *
400 | * @since 1.0.0
401 | *
402 | * @param bool $limit_site_items Limit activity items to the site
403 | */
404 | return (bool) apply_filters( 'bp_multiblog_mode_activity_limit_site_items', $limit_site_items );
405 | }
406 |
407 | /**
408 | * Return whether to limit the activity stream to content of site members
409 | *
410 | * This concerns activity items that are created in the context of the wider network.
411 | * It may effect in blocking items that are created by retired/removed site members.
412 | *
413 | * @since 1.0.0
414 | *
415 | * @return bool Limit activity items to site members
416 | */
417 | function bp_multiblog_mode_activity_limit_site_members() {
418 |
419 | // Prefer the Site Members setting
420 | $limit_site_members = bp_multiblog_mode_limit_site_members();
421 |
422 | // Default to the Activity Site Members setting
423 | if ( ! $limit_site_members ) {
424 | $limit_site_members = get_option( '_bp_multiblog_mode_activity_limit_site_members', false );
425 | }
426 |
427 | /**
428 | * Filter whether to limit the activity stream to content of site members
429 | *
430 | * @since 1.0.0
431 | *
432 | * @param bool $limit_site_members Limit activity items to site members
433 | */
434 | return (bool) apply_filters( 'bp_multiblog_mode_activity_limit_site_members', $limit_site_members );
435 | }
436 |
437 | /**
438 | * Modify the activity query WHERE statements
439 | *
440 | * @see BP_Activity_Activity::get()
441 | *
442 | * @since 1.0.0
443 | *
444 | * @param array $where Query WHERE statements
445 | * @param array $args Query arguments
446 | * @return array Query WHERE statements
447 | */
448 | function bp_multiblog_mode_activity_limit_stream( $where, $args ) {
449 | global $wpdb;
450 |
451 | // Bail when Multiblog is not enabled
452 | if ( ! bp_multiblog_mode_is_enabled() )
453 | return $where;
454 |
455 | // Get BuddyPress
456 | $bp = buddypress();
457 |
458 | // Exclude activity items from deactivated components, except Blogs
459 | $components = array_diff( (array) $bp->deactivated_components, array( 'blogs' ) );
460 |
461 | if ( $components ) {
462 | $components = "'" . implode( "','", $components ) . "'";
463 |
464 | // Activity item(s) should not be from deactivated components
465 | $where['bp_multiblog_mode_exclude_deactivated_components'] = "a.component NOT IN ({$components})";
466 | }
467 |
468 | // Limit activity items belonging to the current site
469 | if ( bp_multiblog_mode_activity_limit_site_items() ) {
470 | /**
471 | * Column 'item_id' can also mean id from activity/forums/groups etc.
472 | * components, so only filter blogs component activities.
473 | */
474 | $where['bp_multiblog_mode_activity_limit_site_items'] = $wpdb->prepare( "(a.item_id = %d OR a.component <> %s)", get_current_blog_id(), 'blogs' );
475 | }
476 |
477 | // Limit activity items created by site members
478 | if ( bp_multiblog_mode_activity_limit_site_members() ) {
479 |
480 | // Get the site members
481 | $site_members = implode( ',', bp_multiblog_mode_get_site_users() );
482 |
483 | // Activity item creator(s) should be a site member
484 | $where['bp_multiblog_mode_activity_limit_site_members'] = "a.user_id IN ({$site_members})";
485 | }
486 |
487 | return $where;
488 | }
489 |
490 | /** XProfile ************************************************************/
491 |
492 | /**
493 | * Return the XProfile field group's Multiblog sites
494 | *
495 | * @see BP_XProfile_Field::get_member_types()
496 | *
497 | * @since 1.0.0
498 | *
499 | * @param int $group_id XProfile group id
500 | * @return array Site ids
501 | */
502 | function bp_multiblog_mode_xprofile_get_group_sites( $group_id ) {
503 |
504 | // Get profile group meta
505 | $raw_sites = bp_xprofile_get_meta( $group_id, 'group', 'multiblog_site', false );
506 |
507 | // If `$raw_sites` is not an array, it probably means this is a new group (id=0).
508 | if ( ! is_array( $raw_sites ) ) {
509 | $raw_sites = array();
510 | }
511 |
512 | // If '_none' is found in the array, it overrides all sites.
513 | $sites = array();
514 | if ( ! in_array( '_none', $raw_sites ) ) {
515 | $enabled_sites = bp_multiblog_mode_get_enabled_sites( array( 'fields' => 'ids' ) );
516 |
517 | // Eliminate invalid sites saved in the database.
518 | foreach ( $raw_sites as $raw_site ) {
519 | // The root blog is a special case - it cannot be Multiblog enabled
520 | if ( bp_multiblog_mode_is_root_blog( $raw_site ) || in_array( $raw_site, $enabled_sites ) ) {
521 | $sites[] = $raw_site;
522 | }
523 | }
524 |
525 | // If no sites have been saved, intepret as *all* sites.
526 | if ( empty( $sites ) ) {
527 | $sites = array_values( $enabled_sites );
528 |
529 | // + the root blog
530 | $sites[] = bp_multiblog_mode_get_root_blog_id();
531 | }
532 | }
533 |
534 | return $sites;
535 | }
536 |
537 | /**
538 | * Modify the profile groups collection
539 | *
540 | * @since 1.0.0
541 | *
542 | * @param array $groups Profile groups
543 | * @param array $args Query arguments
544 | * @return array Profile groups
545 | */
546 | function bp_multiblog_mode_xprofile_get_groups( $groups, $args ) {
547 |
548 | // Are we in the network admin?
549 | $network = is_network_admin() ? '-network' : '';
550 |
551 | // Not when editing profile fields
552 | if ( ! is_admin() || "users_page_bp-profile-setup{$network}" !== get_current_screen()->id ) {
553 |
554 | // Eliminate unassigned groups for the current site
555 | foreach ( $groups as $k => $group ) {
556 | if ( ! in_array( get_current_blog_id(), bp_multiblog_mode_xprofile_get_group_sites( $group->id ) ) ) {
557 | unset( $groups[ $k ] );
558 | }
559 | }
560 |
561 | $groups = array_values( $groups );
562 | }
563 |
564 | return $groups;
565 | }
566 |
567 | /** Files ***************************************************************/
568 |
569 | /**
570 | * Return whether the site uses the root's avatar uploads
571 | *
572 | * @since 1.0.0
573 | *
574 | * @uses apply_filters() Calls 'bp_multiblog_mode_use_root_avatar_uploads'
575 | *
576 | * @return bool Use root avatar uploads
577 | */
578 | function bp_multiblog_mode_use_root_avatar_uploads() {
579 | $use_root_avatar_uploads = ! get_option( '_bp_multiblog_mode_avatar_uploads', false );
580 |
581 | /**
582 | * Filter whether to use the root's avatar uploads
583 | *
584 | * @since 1.0.0
585 | *
586 | * @param bool $use_root_avatar_uploads Use the root's avatar uploads
587 | */
588 | return (bool) apply_filters( 'bp_multiblog_mode_use_root_avatar_uploads', $use_root_avatar_uploads );
589 | }
590 |
591 | /**
592 | * Return whether the site uses the root's file uploads
593 | *
594 | * @since 1.0.0
595 | *
596 | * @uses apply_filters() Calls 'bp_multiblog_mode_use_root_file_uploads'
597 | *
598 | * @return bool Use root file uploads
599 | */
600 | function bp_multiblog_mode_use_root_file_uploads() {
601 | $use_root_file_uploads = ! get_option( '_bp_multiblog_mode_file_uploads', false );
602 |
603 | /**
604 | * Filter whether to use the root's file uploads
605 | *
606 | * @since 1.0.0
607 | *
608 | * @param bool $use_root_file_uploads Use the root's file uploads
609 | */
610 | return (bool) apply_filters( 'bp_multiblog_mode_use_root_file_uploads', $use_root_file_uploads );
611 | }
612 |
613 | /**
614 | * Define the upload directory at the root blog
615 | *
616 | * The upload dir is fetched once and stored in the BP global. So to
617 | * override this we predefine the upload dir early, before BP tries to
618 | * set it. Deviations from this directory are counted for in filters.
619 | *
620 | * @see bp_upload_dir()
621 | *
622 | * @since 1.0.0
623 | *
624 | * @uses do_action() Calls 'bp_multiblog_mode_set_root_upload_dir'
625 | */
626 | function bp_multiblog_mode_set_root_upload_dir() {
627 | $bp = buddypress();
628 |
629 | if ( empty( $bp->upload_dir ) && bp_multiblog_mode_is_enabled() && bp_multiblog_mode_use_root_file_uploads() ) {
630 |
631 | // Juggle to root blog.
632 | switch_to_blog( bp_multiblog_mode_get_root_blog_id() );
633 |
634 | // Get the upload directory (for root blog).
635 | $wp_upload_dir = wp_upload_dir();
636 |
637 | // Juggle back to current blog.
638 | restore_current_blog();
639 |
640 | // Bail if an error occurred.
641 | if ( ! empty( $wp_upload_dir['error'] ) ) {
642 | return false;
643 | }
644 |
645 | $bp->upload_dir = $wp_upload_dir;
646 |
647 | /**
648 | * Act after BP's upload directory is changed to BP's root upload directory
649 | *
650 | * @since 1.0.0
651 | */
652 | do_action( 'bp_multiblog_mode_set_root_upload_dir' );
653 | }
654 | }
655 |
656 | /**
657 | * Return the upload dir for the given site
658 | *
659 | * @since 1.0.0
660 | *
661 | * @uses apply_filters() Calls 'bp_multiblog_mode_get_upload_dir'
662 | *
663 | * @param int $site_id Optional. Site id. Defaults to the current site id.
664 | * @return array Root upload dir data
665 | */
666 | function bp_multiblog_mode_get_upload_dir( $site_id = 0 ) {
667 | $plugin = bp_multiblog_mode();
668 |
669 | if ( empty( $plugin->upload_dir ) ) {
670 | if ( empty( $site_id ) ) {
671 | $site_id = get_current_blog_id();
672 | }
673 |
674 | switch_to_blog( $site_id );
675 |
676 | // Get root upload dir
677 | $upload_dir = wp_upload_dir();
678 |
679 | restore_current_blog();
680 |
681 | // Bail when an error occurred
682 | if ( ! empty( $upload_dir['error'] ) )
683 | return false;
684 |
685 | $plugin->upload_dir = $upload_dir;
686 | }
687 |
688 | /**
689 | * Filter the site's upload directory
690 | *
691 | * @since 1.0.0
692 | *
693 | * @param bool $upload_dir The site's upload directory
694 | * @param int $site_id Site id
695 | */
696 | return apply_filters( 'bp_multiblog_mode_get_upload_dir', $plugin->upload_dir, $site_id );
697 | }
698 |
699 | /**
700 | * Return whether to modify the avatar upload directory
701 | *
702 | * @since 1.0.0
703 | *
704 | * @return bool Modify the avatar upload dir
705 | */
706 | function bp_multiblog_mode_modify_avatar_upload_dir() {
707 | $use_file_uploads = bp_multiblog_mode_use_root_file_uploads();
708 | $use_avatar_uploads = bp_multiblog_mode_use_root_avatar_uploads();
709 |
710 | /**
711 | * Modify the avatar upload directory when:
712 | * - Multiblog mode is enabled
713 | * - Upload dir is not overloaded and avatars should use the root dir
714 | * - OR Upload dir *is* overloaded and avatars should *not* use the root dir
715 | *
716 | * In either other case (both (not) from root), no filtering is needed.
717 | */
718 | return bp_multiblog_mode_is_enabled() && ( ( ! $use_file_uploads && $use_avatar_uploads ) || ( $use_file_uploads && ! $use_avatar_uploads ) );
719 | }
720 |
721 | /**
722 | * Modify the avatar's upload path
723 | *
724 | * @since 1.0.0
725 | *
726 | * @param string $path Avatar upload path
727 | * @return string Avatar upload path
728 | */
729 | function bp_multiblog_mode_core_avatar_upload_path( $path ) {
730 |
731 | // Filtering required
732 | if ( bp_multiblog_mode_modify_avatar_upload_dir() && ! defined( 'BP_AVATAR_UPLOAD_PATH' ) ) {
733 | $uploads = bp_multiblog_mode_get_upload_dir(
734 | bp_multiblog_mode_use_root_avatar_uploads()
735 | ? bp_multiblog_mode_get_root_blog_id()
736 | : 0
737 | );
738 |
739 | if ( $uploads ) {
740 | $path = $uploads['basedir'];
741 | }
742 | }
743 |
744 | return $path;
745 | }
746 |
747 | /**
748 | * Modify the avatar's base url
749 | *
750 | * @since 1.0.0
751 | *
752 | * @param string $url Avatar base url
753 | * @return string Avatar base url
754 | */
755 | function bp_multiblog_mode_core_avatar_url( $url ) {
756 |
757 | // Filtering required
758 | if ( bp_multiblog_mode_modify_avatar_upload_dir() && ! defined( 'BP_AVATAR_URL' ) ) {
759 | $uploads = bp_multiblog_mode_get_upload_dir(
760 | bp_multiblog_mode_use_root_avatar_uploads()
761 | ? bp_multiblog_mode_get_root_blog_id()
762 | : 0
763 | );
764 |
765 | if ( $uploads ) {
766 | $url = $uploads['baseurl'];
767 |
768 | if ( is_ssl() ) {
769 | $url = str_replace( 'http://', 'https://', $url );
770 | }
771 | }
772 | }
773 |
774 | return $url;
775 | }
776 |
--------------------------------------------------------------------------------
/includes/index.php:
--------------------------------------------------------------------------------
1 | array(
26 | 'title' => esc_html__( 'General Settings', 'bp-multiblog-mode' ),
27 | 'callback' => 'bp_multiblog_mode_admin_setting_callback_general_network_section',
28 | 'page' => 'bp-multiblog-mode-network',
29 | ),
30 |
31 | // General settings
32 | 'bp_multiblog_mode_settings_general' => array(
33 | 'title' => esc_html__( 'General Settings', 'bp-multiblog-mode' ),
34 | 'callback' => 'bp_multiblog_mode_admin_setting_callback_general_section',
35 | 'page' => 'bp-multiblog-mode',
36 | ),
37 |
38 | // Profile settings
39 | 'bp_multiblog_mode_settings_profile' => array(
40 | 'title' => esc_html__( 'Profile Settings', 'bp-multiblog-mode' ),
41 | 'callback' => 'bp_multiblog_mode_admin_setting_callback_profile_section',
42 | 'page' => 'bp-multiblog-mode',
43 | ),
44 | ) );
45 | }
46 |
47 | /**
48 | * Return the plugin's settings fields
49 | *
50 | * @since 1.0.0
51 | *
52 | * @uses apply_filters() Calls 'bp_multiblog_mode_admin_get_settings_fields'
53 | * @return array Settings fields
54 | */
55 | function bp_multiblog_mode_admin_get_settings_fields() {
56 |
57 | // Define settings fields
58 | $fields = array(
59 |
60 | // General Network settings
61 | 'bp_multiblog_mode_settings_general_network' => array(
62 |
63 | // Sites
64 | '_bp_multiblog_mode_sites' => array(
65 | 'title' => esc_html__( 'Sites', 'bp-multiblog-mode' ),
66 | 'callback' => 'bp_multiblog_mode_admin_setting_callback_sites',
67 | 'sanitize_callback' => false, // We do our own saving of this field
68 | 'args' => array()
69 | ),
70 | ),
71 |
72 | // General settings
73 | 'bp_multiblog_mode_settings_general' => array(
74 |
75 | // Members
76 | '_bp_multiblog_mode_site_members' => array(
77 | 'title' => esc_html__( 'Members', 'bp-multiblog-mode' ),
78 | 'callback' => 'bp_multiblog_mode_admin_setting_callback_site_members',
79 | 'sanitize_callback' => 'intval',
80 | 'args' => array()
81 | ),
82 |
83 | // Taxonomy terms
84 | '_bp_multiblog_mode_taxonomy_terms' => array(
85 | 'title' => esc_html__( 'Taxonomy terms', 'bp-multiblog-mode' ),
86 | 'callback' => 'bp_multiblog_mode_admin_setting_callback_taxonomy_terms',
87 | 'sanitize_callback' => 'intval',
88 | 'args' => array()
89 | ),
90 | ),
91 |
92 | // Profile settings
93 | 'bp_multiblog_mode_settings_profile' => array(
94 |
95 |
96 | // Avatar uploads
97 | '_bp_multiblog_mode_avatar_uploads' => array(
98 | 'title' => esc_html__( 'Avatar uploads', 'bp-multiblog-mode' ),
99 | 'callback' => 'bp_multiblog_mode_admin_setting_callback_avatar_uploads',
100 | 'sanitize_callback' => 'intval',
101 | 'args' => array()
102 | ),
103 |
104 | // File uploads
105 | '_bp_multiblog_mode_file_uploads' => array(
106 | 'title' => esc_html__( 'File uploads', 'bp-multiblog-mode' ),
107 | 'callback' => 'bp_multiblog_mode_admin_setting_callback_file_uploads',
108 | 'sanitize_callback' => 'intval',
109 | 'args' => array()
110 | ),
111 | ),
112 | );
113 |
114 | // Activity
115 | if ( bp_is_active( 'activity' ) ) {
116 |
117 | // Activity Stream
118 | $fields['bp_multiblog_mode_settings_general']['_bp_multiblog_mode_activity_stream'] = array(
119 | 'title' => esc_html__( 'Activity stream', 'bp-multiblog-mode' ),
120 | 'callback' => 'bp_multiblog_mode_admin_setting_callback_activity_stream',
121 | 'sanitize_callback' => 'intval',
122 | 'args' => array()
123 | );
124 |
125 | // Activity Stream Site Members
126 | if ( ! bp_multiblog_mode_limit_site_members() ) {
127 | $fields['bp_multiblog_mode_settings_general']['_bp_multiblog_mode_activity_site_members'] = array(
128 | /* Field input is in the 'Activity stream' setting */
129 | 'sanitize_callback' => 'intval',
130 | 'args' => array()
131 | );
132 | }
133 | }
134 |
135 | // Avatar uploads is disabled
136 | if ( bp_disable_avatar_uploads( false ) ) {
137 | unset( $fields['bp_multiblog_mode_settings_profile']['_bp_multiblog_mode_avatar_uploads'] );
138 | }
139 |
140 | return (array) apply_filters( 'bp_multiblog_mode_admin_get_settings_fields', $fields );
141 | }
142 |
143 | /**
144 | * Get settings fields by section
145 | *
146 | * @since 1.0.0
147 | *
148 | * @param string $section_id
149 | * @return array|bool Array of fields or False when section is invalid
150 | */
151 | function bp_multiblog_mode_admin_get_settings_fields_for_section( $section_id = '' ) {
152 |
153 | // Bail when section is empty
154 | if ( empty( $section_id ) )
155 | return false;
156 |
157 | $fields = bp_multiblog_mode_admin_get_settings_fields();
158 | $retval = isset( $fields[$section_id] ) ? $fields[$section_id] : false;
159 |
160 | return $retval;
161 | }
162 |
163 | /**
164 | * Return whether the admin page has registered settings
165 | *
166 | * @since 1.0.0
167 | *
168 | * @param string $page
169 | * @return bool Does the admin page have settings?
170 | */
171 | function bp_multiblog_mode_admin_page_has_settings( $page = '' ) {
172 |
173 | // Bail when page is empty
174 | if ( empty( $page ) )
175 | return false;
176 |
177 | // Loop through the available sections
178 | $sections = wp_list_filter( bp_multiblog_mode_admin_get_settings_sections(), array( 'page' => $page ) );
179 | foreach ( (array) $sections as $section_id => $section ) {
180 |
181 | // Find out whether the section has fields
182 | $fields = bp_multiblog_mode_admin_get_settings_fields_for_section( $section_id );
183 | if ( ! empty( $fields ) ) {
184 | return true;
185 | }
186 | }
187 |
188 | return false;
189 | }
190 |
191 | /** General Network Section ***************************************************/
192 |
193 | /**
194 | * Display the description of the General Network settings section
195 | *
196 | * @since 1.0.0
197 | */
198 | function bp_multiblog_mode_admin_setting_callback_general_network_section() { /* Nothing to show */ }
199 |
200 | /**
201 | * Display the enable Multiblog per site setting field
202 | *
203 | * @since 1.0.0
204 | */
205 | function bp_multiblog_mode_admin_setting_callback_sites() {
206 |
207 | // Get all sites of the current network
208 | $sites = bp_multiblog_mode_get_sites(); ?>
209 |
210 |
211 |
212 |
269 |
270 |
271 |
272 |
283 |
284 |
285 |
286 |
295 |
296 | />
297 |
298 |
299 |
308 |
309 | />
310 |
311 |
312 |
321 |
322 |
323 |
324 |
325 | />
326 |
327 |
328 |
329 |
330 |
331 |
332 | />
333 |
334 |
335 |
336 |
354 |
355 | />
356 |
357 |
358 |
367 |
368 | />
369 |
370 |
371 | admin->settings_page;
388 |
389 | // For backcompat, check tabbed header
390 | $is_tabbed_header = function_exists( 'bp_core_admin_tabbed_screen_header' );
391 |
392 | if ( $is_tabbed_header ) : ?>
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
419 |
420 |
421 |
422 |
423 |
424 | $settings ) {
455 | foreach( $settings as $setting_name => $setting ) {
456 | $value = isset( $_POST[$setting_name] ) ? $_POST[$setting_name] : '';
457 |
458 | bp_update_option( $setting_name, $value );
459 | }
460 | }
461 | }
462 |
463 | bp_core_redirect( add_query_arg( array( 'page' => 'bp-multiblog-mode', 'updated' => 'true' ), bp_get_admin_url( 'admin.php' ) ) );
464 | }
465 | }
466 |
--------------------------------------------------------------------------------
/includes/sub-actions.php:
--------------------------------------------------------------------------------
1 |