Generate secure URL external in WordPress - php

I'm using the function esc_url_raw..
WordPress function:
esc_url_raw( string $url, array $protocols = null )
How do I print a url with "https"?
Example:
input: http://example.com
ouput: https://example.com
Doc Function

You can provide the acceptable protocols in the $protocols variable. It can be a array() of protocols like http, https. You can refer wp_allowed_protocols for allowed protocols.
For your answer you can provide an array for $protocols as array('http', 'https') as the argument to esc_url_raw.
If you are actually looking to convert a URL from http to https then you can define something like:
function convert_to_https(url){
$new_url = preg_replace("/^http:/i", "https:", $url);
return $new_url;
}
$https_url = convert_to_https('http://example.com');
echo $https_url; // https://example.com
// then escape the URL
esc_url_raw($https_url);

Related

How can I check if a relative URL is the current one in PHP?

I'm looking to make a PHP function that takes in a relative URL and returns whether that is this URL.
<?PHP
function isCurrentPage($page)
{
//Magic
}
?>
this will be passed values such as "/", "/foo/bar", page.php, or even "foo/page.php?parameter=value".
My first attempt involved using $page == $_SERVER["REQUEST_URI"], but that says "/foo/bar" != "/foo/bar/". That isn't much of an issue, but the difficulty comes with it saying "/foo/bar" != "/foo/bar/index.php?parameter=value". For my purposes, I need it to say that these are equivalent.
How can I tell if the current URL is one passed to this function, with the given restrictions? I would prefer a simple, robust solution that is guaranteed to work for the next 5 years, as this is for a long-term, high-use project. Old, non-deprecated functions andor regexes are preferable.
To synopsize, the method must return true when on the url http://example.com/foo/bar:
isCurrentPage("http://example.com/foo/bar")
isCurrentPage("http://example.com/foo/bar/")
isCurrentPage("http://example.com/foo/bar/index.php")
isCurrentPage("http://example.com/foo/bar/index.phps")
isCurrentPage("http://example.com/foo/bar/index.phtml")
isCurrentPage("/foo/bar")
isCurrentPage("/foo/bar/")
isCurrentPage("/foo/bar/index.php")
isCurrentPage("/foo/bar?parameter=value")
isCurrentPage("/foo/bar/?parameter=value")
isCurrentPage("/foo/bar/index.php?parameter=value")
isCurrentPage("/foo/bar/index.php#id")
isCurrentPage("#id")
isCurrentPage("index.php")
isCurrentPage("index.php?parameter=value")
et cetera.
You might be able to use the parse_url() function to break apart your URL and get rid of all the non important data such as the query string.
Here is a simple example:
$url = 'http://yoursite.com/foo/bar?some=param';
$urlParts = parse_url($url);
// Array
// (
// [scheme] => http
// [host] => yoursite.com
// [path] => /foo/bar
// [query] => ?some=param
// )
You'll now be able to compare the $urlParts['path'] against your list of known paths...
How about:
function isCurrentPage($page)
{
//Magic
$page = preg_replace('/https?:\/\/[a-zA-Z0-9_\.\-]+/', '', $page);
$url = 'http';
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
$url .= 's';
}
$url .= '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . $page;
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
/* Get the HTML or whatever is linked in $url. */
$response = curl_exec($handle);
/* Check for 404 (file not found). */
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
return $httpCode != 404;
}

How to get the scheme when no http:// or https:// is being specified?

I would like for users to be able to enter their company website URL in their company setup dialog, but I need to validate that. Apart from the typical sanitization functions, I would like to check if the URL scheme is http:// or https:// without the assumption the user has already entered it.
My function already parses the entered url to detect the scheme with a regex, but I would like to (ideally) check the URL from the server ala file_get_contents or parse_url and get the scheme, but I don't know how could I do it.
Take a look at parse_url(). The scheme will be returned in the scheme element of the array.
Edit 1
Partial URLs are also accepted, parse_url() tries its best to parse them correctly.
If the scheme is not present in the URL, then the scheme element will be missing.
Edit 2
As #BenediktOlek says, you can use cURL to query the server:
$curl = curl_init();
curl_setopt_array(
$curl,
array(
CURLOPT_URL => 'http://www.example.com/',
CURLOPT_HEADER => TRUE, // Output the response headers
CURLOPT_RETURNTRANSFER => TRUE, // Return output as a string
CURLOPT_NOBODY => TRUE // Use request method "HEAD"
)
);
$curlData = curl_exec($curl);
curl_close($curl);
If the server requires an HTTPS connection, and is correctly configured, then it should return a Location: header with an HTTPS URL.
You could use the cURL module to query the Server. But I guess it is safe to assume http. A proper configured webserver should redirect if http is not allowed.
More on cURL here.
Using parse_url() with parameter PHP_URL_SCHEME like this:
$scheme = parse_url( $url, PHP_URL_SCHEME);
if( !in_array( $scheme, array( 'http', 'https'))){
// Wrong URL
}
// Good URL
After comment:
if( strncmp( $url, 'http://', 7)){ // 7 = strlen( 'http://')
// Not secured
} else if (strncmp( $url, 'https://', 8)) {
// Secured
} else if ( strpos($url, '://') !== false){
// ftp://, sftp:// and other protocols
// you may do this also by: preg_match and regexp ~^[\w]+://~i - will be more accurate
} else {
// any other URL, www.google.com and so on...
// auto-assue: not secured
}
Or maybe this helps?
NSRange range = [urlName rangeOfString:#"http://"];
//NSLog(#"found or not found");
if (range.location != NSNotFound)
{
//NSLog(#"range is found");
//range.location is start of substring
//range.length is length of substring
} else
{
//NSLog(#"range is not found");
//urlName = #"http://" urlName;
//NSString *string = [NSString stringWithFormat:#"%#%#", #"Hello", #"World"];
urlName = [NSString stringWithFormat:#"%#%#", #"http://",urlName];
//NSLog(#"NEW urlName......%#", urlName);
}

Easy way to get Vimeo id from a vimeo url

I'm trying to get just the id from a vimeo URL. Is there a simpler way than this? All the vimeo video urls I see are always:
https://vimeo.com/29474908
https://vimeo.com/38648446
// VIMEO
$vimeo = $_POST['vimeo'];
function getVimeoInfo($vimeo)
{
$url = parse_url($vimeo);
if($url['host'] !== 'vimeo.com' &&
$url['host'] !== 'www.vimeo.com')
return false;
if (preg_match('~^http://(?:www\.)?vimeo\.com/(?:clip:)?(\d+)~', $vimeo, $match))
{
$id = $match[1];
}
else
{
$id = substr($link,10,strlen($link));
}
if (!function_exists('curl_init')) die('CURL is not installed!');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://vimeo.com/api/v2/video/$id.php");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$output = unserialize(curl_exec($ch));
$output = $output[0];
curl_close($ch);
return $output['id'];
}
$vimeo_id = getVimeoInfo($vimeo);
There are lot many vimeo URLs that are valid. Few examples are
All valid URLs:
http://vimeo.com/6701902
http://vimeo.com/670190233
http://player.vimeo.com/video/67019023
http://player.vimeo.com/video/6701902
http://player.vimeo.com/video/67019022?title=0&byline=0&portrait=0
http://player.vimeo.com/video/6719022?title=0&byline=0&portrait=0
http://vimeo.com/channels/vimeogirls/6701902
http://vimeo.com/channels/vimeogirls/67019023
http://vimeo.com/channels/staffpicks/67019026
http://vimeo.com/15414122
http://vimeo.com/channels/vimeogirls/66882931
All invalid URLs:
http://vimeo.com/videoschool
http://vimeo.com/videoschool/archive/behind_the_scenes
http://vimeo.com/forums/screening_room
http://vimeo.com/forums/screening_room/topic:42708
I wrote this java regex that catches all the above valid URLs and rejects the invalid ones. I m not sure though if they vimeo has more valid URLs.
(https?://)?(www.)?(player.)?vimeo.com/([a-z]*/)*([0-9]{6,11})[?]?.*
Hope this helps...
I think using parse_url() is the best option:
$vimeo = 'https://vimeo.com/29474908';
echo (int) substr(parse_url($vimeo, PHP_URL_PATH), 1);
For those of you who want to see the code fully implemented using PHP, I am using the regex provided by user2200660 and formatted for PHP by Morgan Delaney, here it is:
$vimeo = 'http://player.vimeo.com/video/67019023';
if(preg_match("/(https?:\/\/)?(www\.)?(player\.)?vimeo\.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*/", $vimeo, $output_array)) {
echo "Vimeo ID: $output_array[5]";
}
//outputs: Vimeo ID: 67019023
[Edit] You can now do this all via the API!
If you provide a comma separated list of your Vimeo urls via the "links" parameter to the search endpoint (https://developer.vimeo.com/api/endpoints/videos#GET/videos) we will return those videos as API responses.
e.g.
GET https://api.vimeo.com/videos?links=https://vimeo.com/74648232,https://vimeo.com/232323497
[Original]
Vimeo provides many different type of video urls, some of which do not include the id. To ensure support across all of Vimeo's urls you should ask vimeo directly for the ID.
You can ask vimeo via the oEmbed endpoint.
There are many options, but the easiest option is to make an HTTP GET request to the url https://vimeo.com/api/oembed.json?url={vimeo_url}, replacing {vimeo_url} with the appropriate url.
For example, to get the ID of the url you provided above (https://vimeo.com/29474908) make an HTTP GET request to
https://vimeo.com/api/oembed.json?url=https://vimeo.com/29474908
Parse the JSON response, and grab the video_id parameter.
This should retrieve the ID from all kinds of vimeo urls.
$url = 'https://vimeo.com/cool/29474908?title=0&byline=0&portrait=0';
$urlParts = explode("/", parse_url($url, PHP_URL_PATH));
$videoId = (int)$urlParts[count($urlParts)-1];
A current, working regex:
function getIdFromVimeoURL(url) {
return /(vimeo(pro)?\.com)\/(?:[^\d]+)?(\d+)\??(.*)?$/.exec(url)[3];
}
console.log(getIdFromVimeoURL("https://vimeo.com/channels/staffpicks/272053388"))
console.log(getIdFromVimeoURL("https://vimeo.com/272053388"))
console.log(getIdFromVimeoURL("https://player.vimeo.com/video/272053388"))
// ...etc.
If someone need it in JavaScript based on #user2200660 answer:
function getVimeoVideoId(url){
var regex = new RegExp(/(https?:\/\/)?(www.)?(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*/);
if ( regex.test(url) ) {
return regex.exec(url)[5];
}
}
If you only need the Vimeo ID, you can use the RegExp non-capturing groups:
(?:https?:\/\/)?(?:www\.)?vimeo\.com\/(?:(?:[a-z0-9]*\/)*\/?)?([0-9]+)
A lot of good answers here, specifically #user2200660.
https://stackoverflow.com/a/16841070/3850405
However a use case that has not been supported in the previous answers is this:
https://vimeo.com/showcase/7008490/video/407943692
Regex that can handle it and the other examples:
(https?:\/\/)?(www\.)?(player\.)?vimeo\.com\/?(showcase\/)*([0-9))([a-z]*\/)*([0-9]{6,11})[?]?.*
https://regex101.com/r/p2Kldc/1/
$vimeo = 'http://player.vimeo.com/video/67019023';
if(preg_match("/(https?:\/\/)?(www\.)?(player\.)?vimeo\.com\/?(showcase\/)*([0-9))([a-z]*\/)*([0-9]{6,11})[?]?.*/", $vimeo, $output_array)) {
echo "Vimeo ID: $output_array[6]";
}
Credits to #zeckdude for the original example code in PHP.
https://stackoverflow.com/a/29860052/3850405
In 2022, this is still the one to go with for Vimeo videos:
https://gist.github.com/anjan011/1fcecdc236594e6d700f
(Tested on all the faulty url's given in the comments as well.)

preg_replace http with https

Put simply, I need to check if the string in the variable $url is a simple http, if so, replace it with https - but I can't get it to work - any ideas:
$url="http://www.google.com"; // example http url ##
$url_replaced = preg_replace( '#^http://#','https://', $url ); // replace http with https ##
Cheers!
Why not str_replace ?
$url="http://www.google.com"; // example http url ##
$url = str_replace('http://', 'https://', $url );
echo $url;
preg_replace() is unnecessary here. Just use str_replace().
str_replace('http://', 'https://', $url)
You could always create a simple function that returns the link as secure. Much easier if you need to change a lot of links.
function secureLink($url){
$url = str_replace('http://', 'https://', $url );
return $url;
};
Do NOT use str_replace, as it can happen you will replace string in the middle (if the url is not encoded correctly).
preg_replace("/^http:/i", "https:", $url)
Note the /i parameter for case insensitive and ^ saying it have to start with this string.
http://sandbox.onlinephpfunctions.com/code/3c3882b4640dad9b6988881c420246193194e37e

Finding Subdomain And Adding WWW with REGEX

I'm validating and adding http (or https) to my URL variable with this code :
$url = preg_replace("/[^A-Za-z0-9-\/\.\:]/", "", trim($url));
$url = preg_replace('%^(?!https?://).*%', 'http://$0', $url);
But this isn't enough for me. I need one more step , too . I have to check subdomain. If there isn't any subdomain add www.
For example if there isn't any subdomain and
(after this 2 preg_replace()) if $url is : http://example.com , convert to http://WWW.example.com. If $url is : http://www.example.com, don't touch.
(with preg_replace please)
IN SUMMARY if $url hasn't subdomain and www , add www .
may be easier to use php's url parser.
http://www.php.net/manual/en/function.parse-url.php
I got this:
$url = 'http://teknoblogo.com';
$host = parse_url($url, PHP_URL_HOST);
$arr = explode('.', $host);
echo http_build_url($url,
array(
'host' => !preg_match('/^www\d*\.$/i', $arr[0]) && count($arr) <= 2 ? 'www.' . $host : $host
)
);
See also:
parse_url()
http_build_url()
Without TLD lookup tables, the only way I imagine you can do this is if you know your domain already:
$domain = 'example.com';
$url = preg_replace('~^(https?://)(' . preg_quote($domain, '~') . ')(.*)~i', '$1www.$2$3');

Categories