How to set dynamic `home` and `siteurl` in WordPress? - php

I config the multi-language setting dynamically using the locale filter. Which fetch the sub-domain name to determine the language.
function load_custom_language($locale) {
// get the locale code according to the sub-domain name.
// en.mysite.com => return `en`
// zh.mysite.com => return `zh_CN`
// tw.mysite.com => return `zh_TW`
// etc..
}
add_filter('locale', 'load_custom_language');
That works for the index page, but when I redirect to another page, because of the settings of home and siteurl, it always redirects my site to the original one (www.mysite.com).
So I'm curious to find a dynamic way to filter the home and siteurl according to the request, because I might use more than one sub-domain for mysite and I have only one settings for the two settings.

You can override the admin settings in the wp-config.php file.
So if you want something dynamic, the following should work:
//presumes server is set up to deliver over https
define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST']);
define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST']);
This needs to added before the line
require_once(ABSPATH . 'wp-settings.php');
or else you may have problems with some content using the wrong URLs, especially theme files.

I've found another pretty way to achieve the work:
After I checked for the source code of the kernel, I found that there are distinct filters called option_xxx on each options.
So, for my task, I tried to use the option_siteurl and option_home filter to hold that options to load, just to prevent the option to load, maintaining the SERVER_NAME it has:
function replace_siteurl($val) {
return 'http://'.$_SERVER['HTTP_HOST'];
}
add_filter('option_siteurl', 'replace_siteurl');
add_filter('option_home', 'replace_siteurl');
Using this way, it has no need to change the wp_config.php file, and can be easily add to a theme or a plugin.

To set dynamically the domain and as well as the protocol (http or https), use:
// Identify the relevant protocol for the current request
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https" : "http";
// Set SITEURL and HOME using a dynamic protocol.
define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']);
define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']);

Related

Code in my wp-config file I do not understand and need help deciphering

I was updating my wp-config file today, and I found a lot of random stuff added to the end which was from a previous host. I deleted it, as it was not necessary, but I also noticed this code which I'm not sure about. I think the first part is for SSL reasons, but I thought that was taken care of elsewhere, not in my config file? Or am I mistaken? I have noticed when doing research in ahrefs that my site suffers from redirect chains related to http > https, so I'm not sure if this is something to do with that?
The rest of this I do not understand at all. Any help would be really appreciated.
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
$_SERVER['HTTPS'] = 'on';
/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');
/**
* Include tweaks requested by hosting providers. You can safely
* remove either the file or comment out the lines below to get
* to a vanilla state.
*/
if (file_exists(ABSPATH . 'hosting_provider_filters.php')) {
include('hosting_provider_filters.php');
}
Thanks for help.
When in doubt its always a good idea to reference - https://github.com/WordPress/WordPress/blob/master/wp-config-sample.php
That aside, the first part you are correct it deals with redirecting to SSL. It is better to use https vs http to avoid the redirect.
Incoming traffic
Request - http > server > redirect to https and returns request
https > server > returns request
The next section is part of a normal wp-config.php file.
The last section is specific to a hosting provider. It mentions it is safe to comment out or remove. If unsure I would contact your current host to see if it is theirs and what it does if so. If not, you are safe to remove.
I will break your code into three parts
1.
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
$_SERVER['HTTPS'] = 'on';
To get information about which protocol used between client and load balancer, we can use the X-Forwarded-Proto request header. Using this header, the client can make an HTTP request to an HTTPS-only resource.
The purpose of HTTP_X_FORWARDED_PROTO is to make sure the connection is secure with ssl
Notice:Not in the original file https://github.com/WordPress/WordPress/blob/master/wp-config-sample.php
2.
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');
ABSPATH is defined and used for two main purposes
contain Absolute path to the WordPress directory
To deny direct access to files
3.
if (file_exists(ABSPATH . 'hosting_provider_filters.php')) {
include('hosting_provider_filters.php');
}
Added by hosting provider
It can be deleted

Using PHP to generate internal links

I'm using a localhost site as the basis for creating other sites from. I'm using php to generate internal links by finding the current domain, and displaying it with a shortcode. I intend to upload my site to a live host and therefore the domain will change, and my internal links won't be broken.
//add shortcode that displays current site name
function GR_site_name(){
$currentDomain = $_SERVER['HTTP_HOST'];
return $currentDomain.'/wordpress';
}
add_shortcode('GR_site_name', 'GR_site_name');
?>
I've tested this by adding the code to live sites and it works perfectly.
I've read the post at how safe is $_SERVER["HTTP_HOST"]? however it details it as 'generally unsafe' due to the script that it runs.
Is $_SERVER['SERVER_NAME'] safer than $_SERVER['HTTP_HOST']? Or are both regarded as bad practice?
Make a config file with define('host','https://example.com') and use host wherever you want and when you upload script to server just change url in config file and you're good to go
Use a combination of the standard WP_HOME & WP_SITEURL constants, along with the site_url() function.
I'd recommend using one local copy of wp-config.php and a different one for the live site, and then add the following to them:
define('WP_SITEURL', 'http://www.example.com/wordpress'); // Or 'http://localhost/wordpress' for the local copy
define('WP_HOME', 'http://www.example.com');
That way, you don't need a custom function or shortcode - you can simply call site_url() wherever you need it to get the URL of your WP site.
Alternatively, if you need to keep the site URL variable and to accept anything that points to it:
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/wordpress');
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/wordpress');
If you need to keep the shortcode for use within the context of a post, you can change it to:
function GR_site_name(){
return site_url();
}
Note that setting WP_HOME and WP_SITEURL override any database setting for the site's URL, and if you visit the Settings->General page, you'll see those two fields are greyed out.

About HTML and attribute href

Good evening guys, I have a problem with the attribute href because I don't know how to access folders, I give an example:
I stay in root/store/products/details.php
I want to go root/index.php
My answer is : How do I arrive to root/index.php ? I has been trying with ../../index but that didn't worked
If root is the base path on your domain, e.g. example.com/root, then if you're at example.com/root/store/products/details.php, you would have a link like below to get to your root. This href will actually work on any page. If you use ../../index.php it will only work on some pages.
Root
This is how I make all of my template links portable.
For files processed Server-Side you would link by using the SERVER_ROOT and for links in an -a href=...' you would use the SITE_ROOT.
define('SERVER_ROOT', dirname( __FILE__ ) . DS);
$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ?
'https://' : 'http://') . $_SERVER['SERVER_NAME'];
if (strlen( $url ) <= 10) $url = null; // For IDE Support
define( 'SITE_ROOT', $url . DS); // The base URL
So to implement the above
Post Score</li>
Use <a href="../../index.php">
Demo Snippet:
var base = 'https://example.com/store/products/details.php'
var relative = '../../index.php'
var target = new URL(relative, base).toString()
console.log(target)
PHP defaults to index.php so you can link to
Link text
By prefixing a URL with /, like "/root/" instead of "root/", you are forcing it to read from the root of your webhost or with a VPS the directory of the website.
If you customised the DirectoryIndex you can do Link

Make WordPress Available from any domain

I'm trying to create a plugin that will allow WordPress to be accessed from any domain, of course provided that the domain is pointed to it.
I have filter hooks for option_siteurl and option_home which is proving to be useful in almost all cases.
However, it doesn't appear to be working for images that are attached to a post nor for header images of themes. It looks like for these, it's taking the database value of options -> siteurl.
I've tried update_option, but that hasn't done the trick either.
I'm using the following code to get the host:
public function getGoodURL() {
$scheme = ($_SERVER["SERVER_PORT"] == 80 ? "http://" : "https://");
$host = $_SERVER["HTTP_HOST"];
return $scheme.$host;
}
Thanks!
Might want to try putting the site url configuration in the config file i.e.:
$domain = sprintf('%s://%s',
$_SERVER['SERVER_PORT'] == 80 ? 'http' : 'https',
$_SERVER['SERVER_NAME']);
define('WP_SITEURL', $domain);
define('WP_HOME', $domain);
That way, your site will always accept the current domain.

Self-referential URLs

What's the most reliable, generic way to construct a self-referential URL? In other words, I want to generate the http://www.site.com[:port] portion of the URL that the user's browser is hitting. I'm using PHP running under Apache.
A few complications:
Relying on $_SERVER["HTTP_HOST"] is dangerous, because that seems to come straight from the HTTP Host header, which someone can forge.
There may or may not be virtual hosts.
There may be a port specified using Apache's Port directive, but that might not be the port that the user specified, if it's behind a load-balancer or proxy.
The port may not actually be part of the URL. For example, 80 and 443 are usually omitted.
PHP's $_SERVER["HTTPS"] doesn't always give a reliable value, especially if you're behind a load-balancer or proxy.
Apache has a UseCanonicalName directive, which affects the values of the SERVER_NAME and SERVER_PORT environment variables. We can assume this is turned on, if that helps.
I would suggest that the only way to be sure and to be secure is to define a constant for the url in some kind of config file for the site. You could generate the constant with $_SERVER['HTTP_HOST'] as a default and replace with a hard coded definition on deployments where security really matters.
define('SITE_URL', $_SERVER['HTTP_HOST']);
and replace as needed:
define('SITE_URL', 'http://foo.bar.com:8080/');
As I recall, you want to do something like this:
$protocol = 'http';
if ( (!empty($_SERVER['HTTPS'])) || ($_SERVER['HTTPS'] == 'off') ) {
$protocol = 'https';
if ($_SERVER['SERVER_PORT'] != 443)
$port = $_SERVER['SERVER_PORT'];
} else if ($_SERVER['SERVER_PORT'] != 80) {
$port = $_SERVER['SERVER_PORT'];
}
// Server name is going to be whatever the virtual host name is set to in your configuration
$address = $protocol . '://' . $_SERVER['SERVER_NAME'];
if (!empty($port))
$address .= ':' . $port
$address .= $_SERVER['REQUEST_URI'];
// Optional, if you want the query string intact
if (!empty($_SERVER['QUERY_STRING']))
$address .= '?' . $_SERVER['QUERY_STRING'];
I haven't tested this code, because I don't have PHP handy at the moment.
The most reliable way is to provide it yourself.
The site should be coded to be hostname neutral, but to know about a special configuration file. This file doesn't get put into source control for the codebase because it belongs to the webserver's configuration. The file is used to set things like the hostname and other webserver-specific parameters. You can accomodate load balancers, changing ports, etc, because you're saying if an HTTP request hits that code, then it can assume however much you will let it assume.
This trick also helps development, incidentally. :-)
$_SERVER["HTTP_HOST"] is probably the best way, after some validation of course.
Yes, the user specifies it and so it cannot be trusted, but you can easily detect when the user is playing games with it.
One idea for validating that $_SERVER['HTTP_HOST'] is valid could be to validate it by DNS. I've used this method in one or two cases without serious consequences to speed and I believe this method fails silently if provided a IP address.
http://www.php.net/manual/en/function.gethostbyname.php
Peusudo code might be:
define('SITEHOME', in_array(gethostbyname($_SERVER['HTTP_HOST']), array(... valid IP's)))
? $_SERVER['HTTP_HOST']
: 'default_hostname';
why {if you wish the user to continue using http:///host:port/ that they are on do you wish to generate full urls}
whan you can use relative urls instead of either
say on page http://xxx:yy/zzz/fff/
you culd use either
../graphics/whatever.jpg
{to go back one directory from current and get http://xxx:yy/zzz/graphics/whatever.jpg
or
/zzz/graphics/whatever.jpg
{to goto site root and work up the directories as specified}
these both avoid mentioning the host:port part and inherit it from the one currently in use

Categories