Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multisite support? #8

Open
roytanck opened this issue Apr 6, 2020 · 3 comments
Open

Multisite support? #8

roytanck opened this issue Apr 6, 2020 · 3 comments

Comments

@roytanck
Copy link

roytanck commented Apr 6, 2020

Thank you for continuing this plugin. Team members found it to work well on a single site WordPress install. We're looking into deploying it on multisite installs as well, and I'm wondering whether this is supported.

The plugin seems to check user roles before determining whether a user's password should expire. On multisite, the same user can have different roles on different subsites. Does Expire User Passwords take this into account? Would you recommend running the plugin in multisite, and if so, should we network-activate it?

@kkerley
Copy link

kkerley commented Feb 8, 2021

I'd also love to know about multisite support.

@kkerley
Copy link

kkerley commented Feb 10, 2021

@roytanck I ended up extending this a bit for multisite. I don't know what your needs are but maybe this can help. I added this function to the very bottom of the expire-user-passwords.php file, right before the final Expire_User_Passwords::instance(); line:

if ( is_multisite() && is_main_site() ) :
	add_action(
		'update_option_user_expass_settings',
		function( $old_value, $new_value ) {
			// Check for the 'sync_settings_to_network' key
			// If present, loop through all spokes and save the main site's option values to each spoke
			if ( array_key_exists( 'sync_settings_to_network', $_REQUEST ) ) :
				global $wpdb;

				// Save the original blog id.
				$original_spoke_id = get_current_blog_id();
				$spoke_ids         = get_sites( [ 'fields' => 'ids' ] );

				write_to_debug_log( 'should broadcast to the entire network' );

				foreach ( $spoke_ids as $id ) :
					switch_to_blog( $id );

					// Get the user_expass_settings option from the spoke
					$spoke_expass_settings = get_option( 'user_expass_settings' );

					// If the option doesn't exist, change this variable into a skeleton object matching the required format
					if ( ! $spoke_expass_settings ) :
						$spoke_expass_settings = [
							'limit' => '',
							'roles' => [],
						];
					endif;

					// and override it with the main site's user_expass_settings values, gathered from the $_REQUEST object
					$spoke_expass_settings['limit'] = $_REQUEST['user_expass_settings']['limit'];
					$spoke_expass_settings['roles'] = $_REQUEST['user_expass_settings']['roles'];

					// Finally, save the option values to the spoke
					update_option( 'user_expass_settings', $spoke_expass_settings );
				endforeach;

				// restore the current spoke and reset the $GLOBALS so WP doesn't think it's still in 'switched' state
				switch_to_blog( $original_spoke_id );
				$GLOBALS['_wp_switched_stack'] = [];
				$GLOBALS['switched']           = false;
			endif;
		},
		10,
		2
	);
endif;

"Spoke" is our internal word for blogs/subsites.

In addition, in render_submenu_page() in includes/class-settings.php, I've updated the form to the following:

			<form method="post" action="options.php">
				<?php

				settings_fields( 'user_expass_settings_page' );

				do_settings_sections( 'user_expass_settings_page' );

				// check for multisite and if this is the master site. If so, output an additional checkbox to allow for network-wide syncing
				if ( is_multisite() && is_main_site() ) :
					?>
					<div class="master-site-controls">
						<label>
							<input type="checkbox" id="sync_settings_to_network" name="sync_settings_to_network" >
							Sync these settings to the entire network? <br />(They can still be overridden on each spoke)
						</label>
					</div>
					<?php
				endif;
				submit_button();

				?>
			</form>

The additional checkbox added to the form, which only appears on the main site of your multisite network, sets a flag in the $_REQUEST object that the function above this form code checks for. If present, it then loops through each blog/subsite/spoke of the network and assigns those settings to each.

It still allows overriding on a specific blog/subsite/spoke and overwriting the overrides if done again from the main site and broadcast out to the network.

Hope this helps.

@roytanck
Copy link
Author

@kkerley Thank you for sharing your code. My team has opted to create our own (internal) plugin solution, which I'm unfortunately unable to share.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants