How to fetch the default domain with WPML active? - wordpress

For a plugin that I code, we use the domain name for the purpose of registering the premium licenses. We check this against our records or whatnot to ensure that they have that site registered and can therefore use the premium features of the plugin.
I'm finding, however, that when users are using WPML with different domains for each language, the registration only works on one default domain as that's the domain name being used for registration.
$domain = get_home_url();
This is essentially the function that I've been using to fetch that information.
Is there a way to fetch that url, but to always retrieve one, constant, default value regardless of which language subdomain is being loaded? Such that if they have French, Spanish, and English, and English is the default, it always returns the English domain?

Use icl_get_home_url(); function what recomends by WPML documentation.
Also, you need to check if WPML is installed and active.
You can do something like
$domain = get_home_url();
if ( function_exists('icl_object_id') ) {
$domain = icl_get_home_url();
}

If you must have the same domain returned always, use get_option( 'home' ); instead, icl_get_home_url() is deprecated and doesn't do what you are asking. At least not anymore... Currently, icl_get_home_url() returns the localized domain instead of the default, just like wpml_home_url(): https://wpml.org/documentation/support/creating-multilingual-wordpress-themes/home-page-link/
There is also WordPress Multi-site to account for though, so I'd recommend the following:
if ( is_multisite() ) {
switch_to_blog( 1 );
$url = get_option( 'home' );
restore_current_blog();
} else {
$url = get_option( 'home' );
}
This bypasses any filtering, and should ensure that you always get the primary url/domain for validation.

Related

Headless Wordpress, Is there a way to access data in wp_options table as REST endpoint?

Wordpress has an awesome REST API interface.
https://developer.wordpress.org/rest-api/reference/
But the content in wp_options table seems to be missing REST support. Is there a way to access the content in wp_otions table as REST endpoint via plugins?. Thanks.
There is the settings endpoint, but it only contains a surprisingly limited amount of them it seems.
This is something you could very easily do yourself though. I'm not sure if any plugins do it, but I also wouldn't recommend a plugin for something that can be done with less than 20 lines of code.
You just need to register a route using register_rest_route() on the rest_api_init hook, and pass it a callback function. You can drop code like this in your functions.php file or create a Must Use Plugin and drop the code in there, either way.
add_action( 'rest_api_init', function () {
register_rest_route( 'my-custom-route/v1', '/opt/', array(
'methods' => 'GET',
'callback' => 'get_rest_option',
//'permission_callback' => function () {
// return current_user_can( 'administrator' );
//}
) );
} );
function get_rest_option( $data ) {
return get_option( $data['option_name'] );
}
The above will give you access to whatever option you want by accessing:
/wp-json/my-custom-route/v1/opt/?option_name=siteurl
I went ahead and dropped an example on a site of mine:
https://xhynk.com/content-mask/wp-json/my-custom-route/v1/opt/?option_name=blogname
https://xhynk.com/content-mask/wp-json/my-custom-route/v1/opt/?option_name=siteurl
However, this will potentially expose anything in your options table. I went ahead and commented out the permission_callback so that any person, signed in or not, can access it. However, I also added a check like this:
function get_rest_option( $data ) {
if( $data['option_name'] === 'siteurl' || $data['option_name'] === 'blogname' ){
return get_option( $data['option_name'] );
} else {
return 'Unauthorized. Use `siteurl` or `blogname`';
}
}
You can see that home will fail: https://xhynk.com/content-mask/wp-json/my-custom-route/v1/opt/?option_name=home
I would recommend adding in a valid array of options, or using the permission_callback in order to lock it down a bit. You could even have an access key instead, and keep that key secret. Either way, be aware of the security implications of exposing your entire wp_options table, and take some sort of preventative measure!

WordPress -Mainintaing URL parameters

I have created a custom table namely company Now I want to load respective company's details based on URL
I am thinking of creating URL such as example.com/?company=1 and example.com/?company=1&depart=2
Now after login employee will be redirected to its respected company URL.
Now based on company URL ($_GET['company'] )I will be setting some global vars which will contain company details such as COMPANY_NAME so that I can access on any page.
With this approach I have to maintain the URL parameters on every page load/redirect. And also maintain global vars.
Please tell me if this is a good approach or if there is any other better way. I don't want to use multisite.
I have started with using query vars
add_filter( 'query_vars', 'addnew_query_vars' );
function addnew_query_vars($vars)
{
$vars[] = 'company';
$vars[] = 'depart';
return $vars;
}
add_action( 'template_redirect', 'setVars' );
function setVars()
{
if($_GET['company']){
set_query_var( 'store',$_GET['company'] );
}else{
set_query_var( 'company',2 );
}
if($_GET['depart']){
set_query_var( 'depart',$_GET['depart'] );
}else{
set_query_var( 'depart',2 );
}
}
If parameters are set in the URL then it will get that param values else it will take the default one (i.e 2 )
Edit
I need to create URLs for each company so that I can send to clients,therefore I have to use URL parameters anyway
Well, that's an old approach, now a days, Wordpress and php even all technologies are very flexible, they provide thousands of different ways to do the same thing.
For your approach, best way is to do the things using Wordpress query param, which is a modified way to make an awesome url.
If you don't prefer to share the company ids on the url then try using php session, which is also a good practise and also you have secure data. but with session you will not be able to share the url, so best way is to use the query param.

How to get Pay Now URL with custom order status in WooCommerce?

I want to get the URL from where the customer can directly pay for their Invoice and also it should work with wc-cancelled and wc-transaction-declined (custom order status).
My Solution
What I'm doing now is created a custom page with my custom get parameters and processing the whole Payment Process as Documentation in Gateway provider Website.
My Problem
But the problem is whenever they update their doc file and plugin I also have to update my code; but if I get the Pay Now URL then WooCommerce and Gateway Plugin will take care of it.
Is there a better solution?
I got the solution in WooCommerce templates/emails/customer-invoice.php file. The function that I was looking for is get_checkout_payment_url().
Usage
$order = wc_get_order($order_id);
$pay_now_url = esc_url( $order->get_checkout_payment_url() );
echo $pay_now_url; //http://example.com/checkout/order-pay/{order_id}?pay_for_order=true&key={order_key}
//http://example.com will be site_url and protocol will depending upon SSL checkout WooCommerce setting.
But this url only works with pending, failed order status; So I used filter woocommerce_valid_order_statuses_for_payment
if (!function_exists('filter_woocommerce_valid_order_statuses_for_payment')) {
//http://woocommerce.wp-a2z.org/oik_api/wc_abstract_orderneeds_payment/
//http://hookr.io/filters/woocommerce_valid_order_statuses_for_payment/
// define the woocommerce_valid_order_statuses_for_payment callbackĀ 
function filter_woocommerce_valid_order_statuses_for_payment( $array, $instance ) {
$my_order_status = array('cancelled', 'transaction-declined');
return array_merge($array, $my_order_status);
}
// add the filterĀ 
add_filter('woocommerce_valid_order_statuses_for_payment', 'filter_woocommerce_valid_order_statuses_for_payment', 10, 2);
}
^^ I added this in my active theme's functions.php file.
Reference:
get_checkout_payment_url()
wc_abstract_orderneeds_payment
woocommerce_valid_order_statuses_for_payment
You can get url with below code but it will work for wc-pending status order only, with the help of order_id or post_id
$order = wc_get_order($order_id);
echo $pay_now_url = $order->get_checkout_payment_url();

Wordpress Private/Public Posts Security.

I have a quick question to ask.
I've setup a wordpress site with custom theme that has the functionality to set posts "Private/Public" where as you can guess all post marked as private can only be seen by users who are logged in, and public everyone can see.
How I accomplished this was using a custom field "access" and each post can set this custom field to private or public in the edit post screen. Then to display these posts I run a custom loop query with a "is_user_logged_in()" conditional statement. It that statement is true I include all posts with the "access" fields set to both "private/public" and if the statement fails ie the user is not logged in only include posts with "access" set to public. I have used similar loop queries for all single page loops etc.
Now while this works a treat I have concerns over how secure this approach is. Thats were your help comes in. How secure do you think this is? Would it be easy to trick the loop into displaying private post to a user thats not logged in? Can you reccommed a better more secure way of handling private/public posts that can be set by a select number of users on the backend?
ideas much appreciated.
Rob.
maybe I understood all wrong , but -
What You describe is just like the wordpress Default behavior for private posts .
Hence , I do not really understand wh you need a custom field for that .
Custom Fields have the habit of being [ab]used for everything, even if not needed :-)
That being said ,you can use the post_status() function to check for your status
if ( get_post_status ( $ID ) == 'private' )
{
// this is 'private';
}
else
{
// this is public 'public';
}
So you could use
get_post_status ( get_the_ID() )
or if you want to put it at the head of the loop after the the_post() part:
if( get_post_status()=='private' ) continue;
you could wrap it also with is_user_logged_in() if you want .
Point is , there is already a default place in wordpress where "private" is defined . so there is no need to define it elsewhere ( like custom field ).
You can even create your own custom post status with register_post_status() ..
the best way IMHO however , is to filter all the posts on the posts_where
add_filter('posts_where', ' privates_control');
function privates_control($where) {
if( is_admin() ) return $where;
global $wpdb;
return " $where AND {$wpdb->posts}.post_status != 'private' "; // or add your custom status
}
This function simply mofifies the query using the posts_where filter. Codex Link
You can modify it to your needs (add / remove conditions / user levels / user control

How to change the value WPLANG in Wordpress by clicking a link (switch language)?

I successfully made files for localization using Gettext (called es.po and es.mo).
So far as I know I can change the language by defining the value of WPLANG in wp-config.php (in this case define ('WPLANG', 'es');)
I would like the user to change his/her preferred language by clicking a link.
What's the best way of doing this?
I accomplished this by building upon the jLanguage Plugin found at http://www.treutech.com/files/wordpress/jLanguage.zip. *The plugin is no longer available from the author's site, so I'm hosting my updated version. This allows you to format your blog posts and pages using the syntax [english][/english]. It passes a querystring to the code to know which language to use. I started by modifiying the code so that it would use the standard two-letter language codes. I also did away with the flags that the code used to represent the various languages. However, after all this, the plugin still only translates the pages or posts. I wanted the rest of the site to be translated based on the user's choice.
WordPress allows for internationalization; however, once you pick a language you are stuck with it till you change it manually. So I created wp-lang.php. It looks first at what language the user chose from the available language links, It then stores that in a SESSION variable so that state will be persistent. Finally, if no choice was made and there is not SESSION variable, the code will look at the default languages for the browser.
Now, all these changes are dependent upon whether you have downloaded a language package that corresponds with the choices of languages on the site. The language MO file contains translations of all the function names in WordPress. So if the user logins into the Admin panel, everything will be translated. If your theme is coded properly, then your menu headings and meta information will be translated as well. After all that, I modified the wp-config file to include wp-lang. Now the site this is set up on will switch between Spanish and English.
*wp-lang.php
session_start();
if ( isset( $_GET['lang'] ) ) {
$_SESSION['WPLANG'] = $_GET['lang'];
define ('WPLANG', $_SESSION[WPLANG]);
} else {
if(isset($_SESSION['WPLANG'])) {
define ('WPLANG', $_SESSION['WPLANG']);
$_GET['lang'] = $_SESSION['WPLANG'];
} else {
if ( isset( $_SERVER["HTTP_ACCEPT_LANGUAGE"] ) ) {
$languages = strtolower( $_SERVER["HTTP_ACCEPT_LANGUAGE"] );
$languages = explode( ",", $languages );
$_SESSION['WPLANG'] = $languages[0];
$_SESSION['WPLANG'] = str_replace("-", "_", $_SESSION['WPLANG']);
$_GET['lang'] = substr($_SESSION['WPLANG'],0,2);
define ('WPLANG', $_SESSION[WPLANG]);
} else {
define ('WPLANG', '');
}
}
}
*wp-config.php - Find the section where the constant WPLANG is defined. Add in the following line just before the WPLANG declaration.
require_once(dirname(__FILE__).'/wp-lang.php');
define ('WPLANG', '');
This page will first check for the default language of the browser and then set the language. If not, the user can also set the language based on the the one they pick from the posts. The language is set in a session variable to hold state for the entire visit.
My 2 cents: I do a similar thing, but I also remove the ?lang=XX parameter from URL.
After all work on language detection is done, I do the 307-redirection in the code, to the same URL (with ?lang=xxx or &lan=xxx removed from it), then die(). That makes the URL clean off the GET variable, clean and potentially safe for bookmarking.
Also I store the language preference in a cookie, to allow user see the same language upon next visit.
My best solution was... (session_start(); on top)
if( !isset( $_GET['lang'] ) && isset($_SESSION['WPLANG']) ) {
define ('WPLANG', $_SESSION['WPLANG']);
} else {
if ( !isset( $_GET['lang'] ) ) {
if ( isset( $_SERVER["HTTP_ACCEPT_LANGUAGE"] ) ) {
$languages = strtolower( $_SERVER["HTTP_ACCEPT_LANGUAGE"] );
$languages = explode( ",", $languages );
$wplang = str_replace("-", "_", $languages[0]);
$_GET['lang'] = substr($wplang,0,2);
}
}
$language = isset( $_GET['lang'] ) ? htmlspecialchars($_GET['lang'], ENT_QUOTES) : 'es';
switch ( $language ) {
case 'en':
define( 'WPLANG', 'en_US' );
$_SESSION['WPLANG'] = 'en_US';
break;
case 'es':
default:
define( 'WPLANG', 'es_ES' );
$_SESSION['WPLANG'] = 'es_ES';
}
}

Resources