moodle_local_treestudyplan/test.php
2024-05-10 15:22:52 +02:00

83 lines
3.0 KiB
PHP

<?php
function sitematch($key,$site){
// Add double slashes to key and site if no scheme is set.
// Basically: if no double slashes present before any dots,shashes or @s.
if(!\preg_match_all('#^[^./@]*?//#',$key )) {
$key = "//".$key;
}
if(!\preg_match_all('#^[^./@]*?//#',$site)) {
$site = "//".$site;
}
// Use parse_url() to split path and host.
$keyurl = (object)\parse_url($key);
$siteurl = (object)\parse_url($site);
// No match if host is empty on key or site
if (empty($keyurl->host) || empty($siteurl->host)) {
return false;
}
if ($keyurl->host == "*") {
// * matches all
return true;
}
// First match the host part.
$keyparts = \array_reverse(\explode(".",$keyurl->host));
$siteparts = \array_reverse(\explode(".",$siteurl->host));
// Trim starting www from both parts, since site.domain and www.site.domain should be treated as the same.
if (($x = \array_pop($keyparts)) != "www") {\array_push($keyparts,$x);}
if (($x = \array_pop($siteparts)) != "www") {\array_push($siteparts,$x);}
for ($i = 0; $i < count($keyparts); $i++) {
// No match if the site does not have a part, but the key does. Unless the key part is *
if (!isset($siteparts[$i]) ) {
if($keyparts[$i] != "*") {
return false;
} else {
$i++; //increment $i by one before break, to make sure the comparison following this loop holds.
break; // Stop comparison. Host part matches.
}
}
// Now do a proper case insensitive check for matching.
// Uses fnmatch to easily handle shell type wildcards.
if ( ! \fnmatch($keyparts[$i],$siteparts[$i],\FNM_CASEFOLD)) {
return false;
}
}
// Fail if the site has a deeper subdomain than the key, unless the deepest key subdomain is *
if ($keyparts[$i-1] != '*' && count($siteparts) > ($i)) {
return false;
}
// If we made it here then the host part matches. Now check the path.
// If path is /*, matches all subpaths including /
$keypath = empty($keyurl->path)?"/":$keyurl->path;
$sitepath = empty($siteurl->path)?"/":$siteurl->path;
// Trim trailing / from both paths before comparison
if (\strlen($sitepath) > 1) {
$sitepath = \rtrim($sitepath,"/");
}
if (\strlen($keypath) > 1) {
$keypath = \rtrim($keypath,"/");
}
// Do a case insensitive fnmatch on the site so wildcards are matched too.
return \fnmatch($keypath,$sitepath,\FNM_CASEFOLD);
}
$tests = [
["*", "https://www.miqra.nl"],
["*/*", "https://www.miqra.nl"],
["*", "https://clients.openedu.nl/fith"],
["clients.openedu.nl/fith", "https://clients.openedu.nl/fith/"],
["clients.openedu.nl/fith/", "https://clients.openedu.nl/fith"]
];
foreach($tests as $test) {
[$key, $site] = $test;
print("Checking key '{$key}' on site '{$site}': " . (sitematch($key,$site)?"MATCH":"FAIL") . "\n");
}