Automatically create site in multisite Wordpress installation - wordpress

I have a multisite Wordpress installation that I want to connect to a different application via webservices. I'm getting a list of users and I need to create sites automatically. I'm not sure how exactly to do that. Any tips would be appreciated. Thanks.

This is handled internally by WordPress using a file called /wp-admin/network/site-new.php by calling the wpmu_create_blog() function.
global $wpdb;
$domain = 'example.com'; // your domain (or subdomain)
$path = '/blog'; // path to your site
$title = 'My Site'; // site title
$user_id = get_current_user_id(); // the user id that owns this site
// hide db errors
$wpdb->hide_errors();
// create the new site
$id = wpmu_create_blog( $domain, $path, $title, $user_id , array( 'public' => true ) );
// enable db errors
$wpdb->show_errors();

Related

How to segregate the Buddypress member page on multisite?

I have a BuddyPress social networks in a multi network WordPress install (WordPress multisite), thanks to LH Buddypress Multi Network plugin.
How can I prevent people from accessing to a profile page from another blog?
For example :
teacherSite, teacherUser
studentSite, studentUser
I have restricted access to site for non-member.
teacherUser can only connect on teacherSite.
And he can’t see in the directory other users from others blogs.
If studentUser knows the teacherUser username or if he finds or tests…
He can go to:
studentSite.domain.com/members/teacherUser/
And he can see the profile of teacherUser even though teacherUser is not linked to studentSite.
Fortunately, there is no information (because everything else is well segregated) except the name and the gravatar.
But he can still make a connection request or send him a private message!
teacherUser will not see any notification on teacherSite. But he will potentially receive an email which will redirect him to studentSite without being able to connect to it.
How to avoid this?
I'm guessing BuddyPress has somewhat the same user management system as WordPress.
We could compare the current user role with the queried user role. If they're different, we block and redirect.
<?php
/**
* Compare the queried user role with the current user role.
* If both don't match restrict profile access and redirect to current user profile.
*
* Case exceptions:
* - IF the current user IS the queried user.
* - IF the current user IS an Admin or Super-Admin.
*/
add_action( 'wp', function() {
if ( is_author() && get_queried_object() instanceof \WP_User ) {
if ( reset( get_queried_object()->roles ) === reset( wp_get_current_user()->roles ) || get_current_user_id() === get_queried_object_id() || current_user_can( 'manage_options' ) ) { // ... #see https://wordpress.org/support/article/roles-and-capabilities/#capability-vs-role-table
return;
} else {
header( 'Refresh: 2; ' . esc_url( get_author_posts_url( get_current_user_id() ) ) );
$args = array(
'back_link' => true,
);
wp_die( "Error, Restricted access. You're not allowed to view this profile.", 'Error, Restricted access', $args );
};
};
} );

Restrict WordPress Rest API requests to my domain

I have a WordPress website which I use just to populate blog posts and some private posts under custom post types. In another website, I am using the REST API to display the posts. If I use software like Postman, I can display data from the REST API.
How can I prevent any unauthorized REST API requests to domain www.example.com ? so if the request is not coming from www.mysite.com, it is blocked?
Basically prevent my custom post types (example.com) to be visible to the rest api if it is not coming from mysite.com
You can Disable External request by adding this in your wp-config.php ( Also, you can specify domain which you don't want to block like this).
define( 'WP_HTTP_BLOCK_EXTERNAL', TRUE );
define( 'WP_ACCESSIBLE_HOSTS', 'example.com, domain.com' );
apply_filters( 'rest_authentication_errors', WP_Error|null|bool )
Filters REST authentication errors.Put code in functions.php in your theme directory.
Complete description : https://developer.wordpress.org/reference/hooks/rest_authentication_errors/
add_filter( 'rest_authentication_errors', 'wpse150207_filter_incoming_connections' );
function wpse150207_filter_incoming_connections( $errors ){
$allowed_ips = array( '127.0.0.1' );
$request_server = $_SERVER['REMOTE_ADDR'];
if( ! in_array( $request_server, $allowed_ips ) )
return new WP_Error( 'forbidden_access', 'Access denied', array( 'status' => 403 ) );
return $errors;
}
One way to restrict REST requests is to hook at rest_api_init with priority 1, and whitelist the IP's you want. In this example, I restrict REST access to the server itself only:
/**
* Disables WordPress Rest API for external requests
*/
add_action('rest_api_init', function() {
$whitelist = ['127.0.0.1', "::1"];
if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
die('REST API is disabled.');
}
}, 1);

How to get all admins of multisite in wordpress

How to get all admins of multisite in wordpress.
I am create custom plugin for this
I am stuck in custom code for get all the admins of multisite in main website.
for ex. my main website is : wyz.com and my second site is : xyz.com/demo.
main website admin is "abc" and for " xyz.com/demo" site admin is "abcde".
Now how i get "abcde" admin in my main website .
In my live site i have currently 6k admins. So i difficult to get this . I am new in multisite wordpress.
To get the data from any of the sub site, you first need to switch to that site using switch_to_blog() function. Then whatever the query you fire, it will give records from that site only. Don't forget to restore it to current site, once you get the data from sub-site. You can restore it using restore_current_blog() function.
To get the all admin users of all the sites, you need to perform the followings:
1) Use wp_get_sites() function to get the blog_id of all the sites.
2) Once you get the blog_id, You need to perform the following loop to get the admin user of each the sites.
Assume that you get $blog as array of blog_ids from wp_get_sites() function
foreach ($blogs as $blog)
{
switch_to_blog( $blog->blog_id ); // blog id which u got from wp_get_sites() function
$users_query = new WP_User_Query( array(
'role' => 'administrator',
'orderby' => 'display_name'
) ); // query to get admin users
$results = $users_query->get_results();
$site_admins .= 'Blog ID: ' . $blog->blog_id . '<pre>' . print_r($results,true) . '</pre>';
}
restore_current_blog();

How to know which website has installed our wordpress plugin?

We are creating a Wordpress plugin and we want to know the urls of the wordpress websites on which our plugin is installed.
What code should we add to the plugin to receive the url of the wordpress website?
We need this information to see what type of websites are installing our plugin.
Note: We will notify users before downloading the plugin and at the time of activation that we will be receiving there website's url.
In a simple way, You can create a get_urls.php in http://example.com/get_urls.php for receiving and storing URLs.
get_urls.php
<?php
if( isset( $_GET['url'] ) ) {
file_put_contents('urls.log', date('[r] ') . $_GET['url'] . "\n", FILE_APPEND );
}
And add below code to your plugin.
add_action( 'activated_plugin', 'send_url_in_activate', 10, 1 );
function send_url_in_activate( $plugin ) {
if( $plugin !== "PLUGIN_DIR" ) { // e.g: woocommerce/woocommerce.php
return;
}
$response = wp_remote_get( 'http://example.com/get_urls.php?url=' . get_site_url() );
}
Don't forget set your plugin dir.

Link login of two completely separate wordpress websites

I have two wordpress websites running on sub-domain of a server like http://first.mywebsites.net and http://second.mywebsites.net
They both are just like private sites, I can see the content of pages if I am logged in to the website otherwise redirected to the login page.
Now what I want is, if I am log in my first website and go to the link of second website in same browser then I am able to see the content of pages as a logged in user.
This must be happen only in a case when the user which is logged in first website having the same user(user registered with same mail id) in database of second website. As in case of my website, mostly users are registered with same mail id in both the websites.
Trying to achieve this by two approaches but still unable to get this by any of them :
Approach 1 : Adding a table to second website and save the user email and a auth key. Using curl to fetch the details and then logged in. This Approach is as mentioned in here : http://carlofontanos.com/auto-login-to-wordpress-from-another-website
But as I have mentioned it previous, that both the website is in my case are having private content, so in this case I am unable to fetch the details using curl. My code for curl is like :
$api_url = "http://second.mywebsites.net/autologin-api/";
// If you are using WordPress on website A, you can do the following to get the currently logged in user:
global $current_user;
$user_email = $current_user->user_email;
// Set the parameters
$params = array(
'action' => 'get_login_key', // The name of the action on Website B
'key' => '54321', // The key that was set on Website B for authentication purposes.
'user_email' => $user_email // Pass the user_email of the currently logged in user in Website A
);
// Send the data using cURL
$ch = curl_init($api_url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$gbi_response = curl_exec($ch);
curl_close($ch);
// Parse the response
parse_str($gbi_response);
print_r($gbi_response);
In this case I am not getting the response, My page redirect me to the login page of second website.
Approach 2 : Trying to do it with the use of cookies as I want to logged in to second website in same browser.
I have added a new cookie in my first website like :
global $current_user;
$user_email = $current_user->user_email;
if($user_email != ''){
$_COOKIE['current_user_mail_id'] = $user_email;
}
echo "<pre>";
print_r($_COOKIE);
echo "</pre>";
and added cookie is showing with the other cookies. But when I am checking this in my second website on same browser like :
echo "<pre>";
print_r($_COOKIE);
echo "</pre>";
The cookie which I have added in my first website is not showing on my second website.
I am not much familiar with cookies, setting auth cookies etc.
Please suggest a solution, how can I achieve this.
You can accomplished by using "Single Signon".
Instruction-
To simplify passing users between our systems I have created this PHP class
that you are welcome to use.
To check if a user is signed in:
$signon = new SingleSignon();
$userId = $signon->checkCookie();
if($userId){
// user is logged in and this is their id
}
else{
// user is not logged in or they are exipred
}
If the user is not logged in then use our api to login then use the following code if the api call is successful.
To set a user as logged in:
$signon = new SingleSignon();
$signon->setCookie($userId);
NOTE: You need to be using ssl for the cookie to be read.
I have gone through the solution provided by Gaurav and find a idea to make this possible for wordpress websites.
Place below mentioned code at the place where you want to put the link to go to your second website :
<?php global $current_user;
$user_email = $current_user->user_email;
$user_login = $current_user->user_login;
if($user_email != ''){
$email_encoded = rtrim(strtr(base64_encode($user_email), '+/', '-_'), '=');
$user_login_encoded = rtrim(strtr(base64_encode($user_login), '+/', '-_'), '=');
echo '<div class="dtNode">Link to second website</div>';
}?>
Now prepare a sso.php file and place it to the root installation of your second site where you want to logged in automatically. Now put the below code there :
<?php
require_once( 'wp-load.php' ); //put correct absolute path for this file
global $wpdb;
if(isset($_GET['key']) && !empty($_GET['key'])){
$email_decoded = base64_decode(strtr($_GET['key'], '-_', '+/'));
$username_decoded = base64_decode(strtr($_GET['detail'], '-_', '+/'));
$received_email = sanitize_text_field($email_decoded);
$received_username = sanitize_text_field($username_decoded);
if( email_exists( $received_email )) {
//get the user id for the user record exists for received email from database
$user_id = $wpdb->get_var($wpdb->prepare("SELECT * FROM wp_users WHERE user_email = %s", $received_email ) );
wp_set_auth_cookie( $user_id); //login the user
wp_redirect( 'http://second.mywebsites.net');
}else {
//register those user whose mail id does not exists in database
if(username_exists( $received_username )){
//if username coming from first site exists in our database for any other user,
//then the email id will be set as username
$userdata = array(
'user_login' => $received_email,
'user_email' => $received_email,
'user_pass' => $received_username, // password will be username always
'first_name' => $received_username, // first name willl be username
'role' => 'subscriber' //register the user with subscriber role only
);
}else {
$userdata = array(
'user_login' => $received_username,
'user_email' => $received_email,
'user_pass' => $received_username, // password will be username always
'first_name' => $received_username, // first name willl be username
'role' => 'subscriber' //register the user with subscriber role only
);
}
$user_id = wp_insert_user( $userdata ) ; // adding user to the database
//On success
if ( ! is_wp_error( $user_id ) ) {
wp_set_auth_cookie( $user_id); //login that newly created user
wp_redirect( 'http://second.mywebsites.net');
}else{
echo "There may be a mismatch of email/username with the existing record.
Check the users with your current email/username or try with any other account.";die;
}
}
die;
} ?>
Above code works for me, you can modify the code as per your needs. For more clear explanation, you can check here : http://www.wptricks24.com/auto-login-one-website-another-wordpress

Resources