I've just finished building my first plugin and have tested it with various plugins on my personal site with no errors. However some users are saying the plugin is causing the following errors for them:
strpos(): Empty needle in
/west/XXXXX/public_html/wp-content/plugins/bot-block/bot-plugin.php on
line 200
On line 200 I have this:
//See if the domain that referred is in the current block url
$pos = strpos( $referrer, $site );
Now I can't see a problem with that line so I'll give you the whole function:
//Check referrer function
function bot_block_parse()
{
//Get the options for the plugin
$options = get_option( 'bot_block' );
//See if the request was from another site
if( isset( $_SERVER['HTTP_REFERER'] ) )
{
//Split the URL into it's components
$referrer = parse_url( $_SERVER['HTTP_REFERER'] );
//Trim the components
$referrer = array_map( 'trim', $referrer );
//Get the domain name
$referrer = $referrer['host'];
//Get the block list
$list = $this->create_block_list();
//Loop through all the blocked domains
foreach( $list as $site )
{
//Trim the domain
$site = trim( $site );
//Set the prefix for domains that aren't sub domains
$prefix = 'www';
//Split domain into smaller components
$domainParts = explode( ".", $referrer );
//See if the domain that referred is in the current block url
$pos = strpos( $referrer, $site );
//See if block subdomains is checked
if( isset( $options['subdomains'] ) )
{
//Check to see if the domain was the current blocked site and if the prefix is not www
if( $pos !== false && $domainParts[0] != $prefix )
{
//Log spam
$this->log_spam( $site );
//Call the redirect function to see where to send the user
$this->bot_block_redirect();
exit;
}
}
//See if the domain was the current site blocked and the prefix is www
if( $pos !== false && $domainParts[0] == $prefix )
{
//Log spam
$this->log_spam( $site );
//Call the redirect function to see where to send the user
$this->bot_block_redirect();
exit;
}
}
}
}
If you need to see the full plugin code I have put it on pastebin here: http://pastebin.com/gw7YbPVa
Can anybody help me figure this out please?
The quick fix is to see if your needle ($site) is empty before attempting to call strpos(). If it is empty, certainly it can't be found in the haystack, so we should skip altogether and set $pos to false.
$pos = strpos( $referrer, $site );
Becomes:
if ( $site == '' || !$site ) {
$pos = false;
} else {
$pos = strpos( $referrer, $site );
}
The better solution is to determine why your $site variable is empty in the first place. Does each child element in $list array contain another array, instead of a string as you expect? You can use var_dump( $site ); in your loop to see the contents of that variable.
Related
I have one website www.example.com it has 5 pages lets say
www.example.com
www.example.com/about-us
www.example.com/terms-of-use
www.example.com/privacy-policy
www.example.com/apps
Now in the last page which is www.example.com/apps, I want following code to be executed in apps landing page:
$user_agent = $_SERVER['HTTP_USER_AGENT'];
if(strpos($user_agent, "Win") !== FALSE){
$url = "http://www.example.com";
}elseif(strpos($user_agent, "Mac") !== FALSE){
$url = "https://itunes.apple.com/us/app/exmaple/idwewew?ls=1&mt=8";
}elseif(strpos($user_agent, "Android") !== FALSE){
$url = "https://play.google.com/store/apps/details?id=com.example";
}
wp_redirect($url, 302); exit;
Which means If user access this page from windows device it will redirect user to home page, if user access this page from android device then goes to google play store and similarly for iOS device...
Now when I put this code in edit page, it wont work...I am using PHP Code Widget plugin
Please help...
Try doing something like this (without PHP Code Widget at all):
// functions.php
function my_page_template_redirect()
{
if ( is_page( 'apps' ) )
{
$user_agent = $_SERVER['HTTP_USER_AGENT'];
if ( strpos( $user_agent, "Win" ) !== false ) {
$url = "http://www.example.com";
} elseif ( strpos( $user_agent, "Mac" ) !== false ) {
$url = "https://itunes.apple.com/us/app/exmaple/idwewew?ls=1&mt=8";
} elseif ( strpos( $user_agent, "Android" ) !== false ){
$url = "https://play.google.com/store/apps/details?id=com.example";
}
wp_redirect( $url, 302 );
exit();
}
}
add_action( 'template_redirect', 'my_page_template_redirect' );
P.S. I didn't test this code, so, please let me know how it works for you.
This is a self Q&A
I found myself often needing to parse a URL supplied by a CMS user to determine if it's an external URL, or an internal one. Often clients want external URL's to be highlighted differently, or to force target="_blank" for them.
So, I want a piece of code that can parse a URL and determine if it's an internal or external URL, and then return a different class and target for either scenario.
This below code takes a URL as a string, then two different class names as strings and compares the URL to the host (I also commented out a WordPress specific piece of code if needed).
function parse_external_url( $url = '', $internal_class = 'internal-link', $external_class = 'external-link') {
// Abort if parameter URL is empty
if( empty($url) ) {
return false;
}
// Parse home URL and parameter URL
$link_url = parse_url( $url );
$home_url = parse_url( $_SERVER['HTTP_HOST'] );
//$home_url = parse_url( home_url() ); // Works for WordPress
// Decide on target
if( empty($link_url['host']) ) {
// Is an internal link
$target = '_self';
$class = $internal_class;
} elseif( $link_url['host'] == $home_url['host'] ) {
// Is an internal link
$target = '_self';
$class = $internal_class;
} else {
// Is an external link
$target = '_blank';
$class = $external_class;
}
// Return array
$output = array(
'class' => $class,
'target' => $target,
'url' => $url
);
return $output;
}
You would use the code like this:
$url_data = parse_external_url( 'http://www.funkhaus.us', 'internal-link-class', 'external-link-class' );
This is a link
This question already has answers here:
How to get host name from this kind of URL?
(2 answers)
Closed 8 years ago.
Is there any way to accept a URL and change it's domain to .com ?
For example if a user were to submit www.example.in, I want to check if the URL is valid, and change that to www.example.com. I have built a regex checker that can check if the URL is valid, but I'm not entirely sure how to check if the given extension is valid, and then to change it to .com
EDIT : To be clear I am not actually going to these URL's. I am getting them submitted as user input in a form, and am simply storing them. These are functions I want to do to the URL before storing, that is all.
Edit 2 : An example to make this clearer -
$url = 'www.example.co.uk'
$newurl = function($url);
echo $newurl
which would yield the output
www.example.com
Are you looking for something like this on the server side to replace a list of selected TLDs to be translated to .coms?
<?php
$url = "www.example.in";
$replacement_tld = "com";
# array of all TLDs you wish to support
$valid_tlds = array("in","co.uk");
# possible TLD source lists
# http://data.iana.org/TLD/tlds-alpha-by-domain.txt
# https://wiki.mozilla.org/TLD_List
# from http://stackoverflow.com/a/10473026/723139
function endsWith($haystack, $needle)
{
$haystack = strtolower($haystack);
$needle = strtolower($needle);
return $needle === "" || substr($haystack, -strlen($needle)) === $needle;
}
foreach($valid_tlds as $tld){
if(endsWith($url, $tld))
{
echo substr($url, 0, -strlen($tld)) . $replacement_tld . "\n";
break;
}
}
?>
Create an empty text file using a text editor such as notepad, and save it as htaccess.txt.
301 (Permanent) Redirect: Point an entire site to a different URL on a permanent basis. This is the most common type of redirect and is useful in most situations. In this example, we are redirecting to the "mt-example.com" domain:
# This allows you to redirect your entire website to any other domain
Redirect 301 / http://mt-example.com/
302 (Temporary) Redirect: Point an entire site to a different temporary URL. This is useful for SEO purposes when you have a temporary landing page and plan to switch back to your main landing page at a later date:
# This allows you to redirect your entire website to any other domain
Redirect 302 / http://mt-example.com/
For more details : http://kb.mediatemple.net/questions/242/How+do+I+redirect+my+site+using+a+.htaccess+file%3F
The question is not entirely clear, I'm assuming you wish to make this logic on PHP part.
Here's useful function to parse such strings:
function parseUrl ( $url )
{
$r = "^(?:(?P<scheme>\w+)://)?";
$r .= "(?:(?P<login>\w+):(?P<pass>\w+)#)?";
$r .= "(?P<host>(?:(?P<subdomain>[\w\.\-]+)\.)?" . "(?P<domain>\w+\.(?P<extension>\w+)))";
$r .= "(?::(?P<port>\d+))?";
$r .= "(?P<path>[\w/]*/(?P<file>\w+(?:\.\w+)?)?)?";
$r .= "(?:\?(?P<arg>[\w=&]+))?";
$r .= "(?:#(?P<anchor>\w+))?";
$r = "!$r!";
preg_match( $r, $url, $out );
return $out;
}
You can parse URL, validate it, and then recreate from resulting array replacing anything you want.
If you want to practice regexp and create own patterns - this site will be best place to do it.
If your goal to route users from one url to another or change URI style, then you need to use mod rewrite.
Actually in this case you will end up configuring your web server, probably virtual host, because it will route only listed domains (those being parked at the server).
To validate a URL in PHP You can use filter_var() .
filter_var($url, FILTER_VALIDATE_URL))
and then to get Top Level Domain (TLD) and replace the it with .com , you can use following function :
$url="http://www.dslreports.in";
$ext="com";
function change_url($url,$ext)
{
if(filter_var($url, FILTER_VALIDATE_URL)) {
$tld = '';
$url_parts = parse_url( (string) $url );
if( is_array( $url_parts ) && isset( $url_parts[ 'host' ] ) )
{
$host_parts = explode( '.', $url_parts[ 'host' ] );
if( is_array( $host_parts ) && count( $host_parts ) > 0 )
{
$tld = array_pop( $host_parts );
}
}
$new_url= str_replace($tld,$ext,$url);
return $new_url;
}else{
return "Not a valid URl";
}
}
echo change_url($url,$ext);
Hope this helps!
I'm getting all ahrefs of a page with this loop:
foreach($html->find('a[href!="#"]') as $ahref) {
$ahrefs++;
}
I want to do something like this:
foreach($html->find('a[href!="#"]') as $ahref) {
if(isexternal($ahref)) {
$external++;
}
$ahrefs++;
}
Where isexternal is a function
function isexternal($url) {
// FOO...
// Test if link is internal/external
if(/*condition is true*/) {
return true;
}
else {
return false;
}
}
Help!
Use parse_url and compare host to your local host (often but not always it's the same as $_SERVER['HTTP_HOST'])
function isexternal($url) {
$components = parse_url($url);
return !empty($components['host']) && strcasecmp($components['host'], 'example.com'); // empty host will indicate url like '/relative.php'
}
Hovewer this will treat www.example.com and example.com as different hosts. If you want all your subdomains to be treated as local links then the function will be somewhat larger:
function isexternal($url) {
$components = parse_url($url);
if ( empty($components['host']) ) return false; // we will treat url like '/relative.php' as relative
if ( strcasecmp($components['host'], 'example.com') === 0 ) return false; // url host looks exactly like the local host
return strrpos(strtolower($components['host']), '.example.com') !== strlen($components['host']) - strlen('.example.com'); // check if the url host is a subdomain
}
This is how you can simply detect external URLs:
$url = 'https://my-domain.com/demo/';
$domain = 'my-domain.com';
$internal = (
false !== stripos( $url, '//' . $domain ) || // include "//my-domain.com" and "http://my-domain.com"
stripos( $url, '.' . $domain ) || // include subdomains, like "www.my-domain.com". DANGEROUS (see below)!
(
0 !== strpos( $url, '//' ) && // exclude protocol relative URLs, like "//example.com"
0 === strpos( $url, '/' ) // include root-relative URLs, like "/demo"
)
);
The above check will treat www.my-domain.com and my-domain.com as being "internal".
Why this rule is dangerous:
The subdomain logic introduces a weakness that could be exploited: When an external URL contains your domain inside the path, for example, https://external.com/www.my-domain.com is treated as internal!
More secure code:
This problem can be eliminated by removing subdomain support (which I suggest to do):
$url = 'https://my-domain.com/demo/';
$domain = 'my-domain.com';
$internal = (
false !== stripos( $url, '//' . $domain ) || // include "//my-domain.com" and "http://my-domain.com"
(
0 !== strpos( $url, '//' ) && // exclude protocol relative URLs, like "//example.com"
0 === strpos( $url, '/' ) // include root-relative URLs, like "/demo"
)
);
function isexternal($url) {
// FOO...
// Test if link is internal/external
if(strpos($url,'domainname.com') !== false || strpos($url,"/") === '0')
{
return true;
}
else
{
return false;
}
}
I know this post is old but here my function i coded right now. Maybe some other need it too.
function IsResourceLocal($url){
if( empty( $url ) ){ return false; }
$urlParsed = parse_url( $url );
$host = $urlParsed['host'];
if( empty( $host ) ){
/* maybe we have a relative link like: /wp-content/uploads/image.jpg */
/* add absolute path to begin and check if file exists */
$doc_root = $_SERVER['DOCUMENT_ROOT'];
$maybefile = $doc_root.$url;
/* Check if file exists */
$fileexists = file_exists ( $maybefile );
if( $fileexists ){
/* maybe you want to convert to full url? */
return true;
}
}
/* strip www. if exists */
$host = str_replace('www.','',$host);
$thishost = $_SERVER['HTTP_HOST'];
/* strip www. if exists */
$thishost = str_replace('www.','',$thishost);
if( $host == $thishost ){
return true;
}
return false;
}
You probably want to check if the link is in the same domain. That will only work though if all your href attributes are absolute and contain the domain. Relative ones like /test/file.html are tricky because one can have folders that have the same name as domains.. So, if you have full url's in each link:
function isexternal($url) {
// Test if link is internal/external
if(stristr($url, "myDomain.com") || strpos($url,"/") == '0')
return true;
else
return false;
}
Suppose I have a function that redirects the page to the given URL (code below). For security reasons, I want to modify it so that it redirects only to the URLs inside my domain.
public static function redirect($num, $url)
{
header($http[$num]);
header ("Location: $url");
}
This is based more like TimWolla's example:
public static function redirect( $num, $url ) {
$host = ( parse_url( $url, PHP_URL_HOST );
if ( !empty( $host ) && $host == $_SERVER[ 'HTTP_HOST' ] ) {
$url = preg_replace( '/[^\w\s\p{L}\d\r?,=#:\/.-]/i', '', urldecode( $url ) );
#header( $http[ $num ] ); //not sure what this is for?
header( "Location: " . $url );
return;
} else return
}
All I have changed is rather than posting an error, the function just returns. Also added a filter to remove characters using a whitelist method.
The concept above is principle to build upon I think.
Use parse_url():
public static function redirect($num, $url)
{
if (parse_url($url, PHP_URL_HOST) != 'example.com') {
trigger_error("Invalid redirection-URL given", E_USER_ERROR);
return;
}
header($http[$num]);
header ("Location: $url");
}
Take a look at http://php.net/manual/en/reserved.variables.server.php.
You can find the host name there and then just do a strpos to ensure that the $url matches
you can find out your current host using $_SERVER['HTTP_HOST'] so you can check if the url contains the host before deciding what to do with it
$pos = strpos($url, $_SERVER['HTTP_HOST']);
if ($pos === false) {
//not on same domain don't redirect
} else {
//on same domain so do redirection
}
I would keep it as simple as possible, using strpos:
if ( strpos( $url, 'yourdomain.com' ) === false )
header('Location: /an/error/page.html');
else
header('Location: '.$url);