I am trying to do this on a standalone WP installation (not multisite). What I am trying to achieve is:
- User saves
domain.comon usermeta. (done) - User creates a new CPT, say
company. Which is accessible via by defaultoriginal.com/company/example-company(done – by default) - I need all the posts created by the user to make available also via
domain.com/company/example-companywhen the usermetadomainis set.
I understand that the DNS and domain should be pointed to current WP installation (irrelevant), but not sure how to map the domain to a permalink.
Algorithm Should Be Something Like This
- Check if
companyCPT single page is shown. - Check if the author set a domain.
- If
domainis set, modify the permalink.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
If you set domain.com as an alias of original.com, in WordPress you have to do nothing to make it works.
The problem is the countrary: once in DNS the 2 domains are aliases, every url of your WordPress will be accessible via user defined domains: domain.com/any/wp/url, but also domain2.com/any/wp/url, domain3.com/any/wp/url and so on…
So, what you have to do, is
- Check if the url is one of the user defined domain
- If so, check if the page requested is a singular CPT and its author
is the one that saved the domain - If not, redirect the request to the original domainù
Let’s assume you save yout original domain in a constant, maybe in wp-config.php
define('ORIGINAL_DOMAIN', 'original.com');
now you can easily implement the workflow described above:
add_action('template_redirect', 'check_request_domain', 1);
function check_request_domain() {
$domain = filter_input(INPUT_SERVER, 'HTTP_HOST', FILTER_SANITIZE_URL);
// strip out the 'www.' part if present
$domain = str_replace( 'www.', '', $domain);
// if the request is from original domain do nothing
if ( $domain === ORIGINAL_DOMAIN ) return;
// if it is not a singular company CPT request redirect to same request
// but on original domain
if ( ! is_singular('company') ) {
redirect_to_original(); // function defined below
}
// if we are here the request is from an user domain and for a singular company request
// let's check if the author of the post has user meta, assuming meta key is `'domain'`
// and the meta value is the same of domain in current url
$meta = get_user_meta( get_queried_object()->post_author, 'domain', TRUE );
if ( $meta !== $domain ) { // meta doesn't match, redirect
redirect_to_original(); // function defined below
} else {
// meta match, only assuring that WordPress will not redirect canonical url
remove_filter('template_redirect', 'redirect_canonical');
}
}
Now let’s write a function to redirect request using current url, but with original domain
/**
* Redirect the request to same url, but using original domain
*/
function redirect_to_original() {
$original = untrailingslashit( home_url() ) . add_query_arg( array() );
wp_safe_redirect( $original, 301 );
exit();
}
The last thing to do is filter the permalink creation to use the user-defined domain for singular company CPT urls:
add_filter( 'post_type_link', 'custom_user_domain_plink', 999, 2 );
function custom_user_domain_plink( $post_link, $post ) {
// we want change permalink only for company cpt posts
if ( $post->post_type !== 'company' ) return $post_link;
// has the user setted a custom domain? If not, do nothing
$custom = get_user_meta( $post->post_author, 'domain', TRUE );
if ( empty($custom) ) return $post_link;
// let's replace the original domain, with the custom one, and return new value
return str_replace( ORIGINAL_DOMAIN, $custom, $post_link);
}
At this point, you have only set DNS for your server, where all the user defined domains are aliases of the original.
Please note code is untested.
Method 2
A simple constant WP_SITEURL could do the trick. I did worked on something similar to it.
The difference is all of the domains were hosted on the same server
and pointed to the root directory.
The procedure i tried –
Checked the host using $_SERVER['HTTP_HOST'] and Validated if it exist on the database.
Comparing your needs, you could check this like –
global $wpdb;
$domain_user = $wpdb->get_var(
"SELECT user_id FROM $wpdb->usermeta".
" WHERE meta_key = 'domain'".
" AND meta_value='". $_SERVER['HTTP_HOST'] ."'"
);
// if an user found, do further processing.
// Exclude posts by other user using pre_get_posts may be.
Next, defined WP_SITEURL and WP_HOME
define( 'MY_SITE_DOMAIN', $_SERVER['HTTP_HOST'] );
if( !defined( 'WP_SITEURL' )):
if( is_ssl())
define( 'WP_SITEURL', 'https://'. MY_SITE_DOMAIN );
else
define( 'WP_SITEURL', 'http://'. MY_SITE_DOMAIN );
endif;
if( !defined( 'WP_HOME' ) ):
define( 'WP_HOME', WP_SITEURL );
endif;
So, all of the links dynamically changed to current host address, and all of them were accessible as like a general wordpress site.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0